转载请标明出处,谢谢!
版本说明:
V1:
2014-3-30
版
版
前言:
因为要进行微信开发,就必须要成为微信开发者,要想成为微信开发者,就必须要有服务器响应微信的 Token 验证,如果没有公网服务器环境,可以去了解下BAE、SAE或阿里云,这里以 BAE 为例。
前提条件:
(1)拥有微信公众平台帐号(申请地址:https://mp.weixin.qq.com/)
(2)拥有百度BAE开发者帐号(申请地址:http://developer.baidu.com/)
(3)搭建好 Java 开发环境,没有搭建好的可参考 Java 开发环境搭建
准备工作:
下载安装 MyEclipse 工具,SVN 代码版本管理工具,SVN 在给百度 BAE 提交 war 包的方法请参考百度开发者文档 SVN 的使用 <http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/manage/svn#SVN.E5.AE.A2.E6.88.B7.E7.AB.AF.E4.BD.BF.E7.94.A8.E8.AF.B4.E6.98.8E>
详细步骤:
1、去BAE快速创建一个JAVA应用
去到百度开放云首页 (http://developer.baidu.com/),点击右上角 “管理控制台” ,进入我的应用页面:如图 1
图 1
点击 “创建应用” 填上应用名称,点击“保存”,如图2
图 2
你就会看到你创建好的应用:(图 3)
图 3
2、添加部署
点击应用图标,查看应用信息,点击“应用引擎” 弹出“部署列表”页面:图 4
图 4
点击“添加部署”,按要求填写, 类型选择 Java-tomcat:图5
图
5
如果部署失败并提示警告,由于 bae 升级到 3.0 版本,实行分批制度,看百度网站公告,如果你没有拿到 BEA 资源,就无法继续进行操作。
成功部署后,是这样的:
3、新建项目
打开 MyEclipse ,新建一个 Web Project :
新建一个 servlet 包,方法是:"src" --> 右键 --> new --> packages, 命名随意,例如 org.ivy.course.servlet
通过向导往包里添加一个能够处理请求的Servlet 类,具体操作时包名右键 --> new --> Servlet:
finish 后,就能看到建好的类,并配有示例代码:
package org.ivy.course.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CoreServlet extends HttpServlet { /** * Constructor of the object. */ public CoreServlet() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); out.println(" <BODY>"); out.print(" This is "); out.print(this.getClass()); out.println(", using the GET method"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); out.println(" <BODY>"); out.print(" This is "); out.print(this.getClass()); out.println(", using the POST method"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init() throws ServletException { // Put your code here } }
同时,配置文件
web.xml 也会自动添加 <servlet>
和 <servlet-mapping>
两个配置项:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>CoreServlet</servlet-name> <servlet-class>org.ivy.course.servlet.CoreServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CoreServlet</servlet-name> <url-pattern>/servlet/CoreServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app
如果你想看看这些代码有什么效果,你可以试着运行工程:run
as --> MyEclipse server Appcation,弹出网页:
我们在上图中的网址后面添加 <url-pattern> 中设定的值 /servlet/CoreServlet
(见 web.xml 文件)并回车,效果如下:
看到这些网页打印的信息,再对比一下代码,你应该能明白上述示例代码的用处了。
我们按控制台那个红色方框,停止运行工程,回到类 CoreServlet,将 doGet 和 doPost 方法里面的代码删掉,并在 doGet 方法中国添加我们的代码:
// my // 微信加密签名 String signature = request.getParameter("signature"); // 时间戮 String timestamp = request.getParameter("timestamp"); // 随机数 String nonce = request.getParameter("nonce"); // 随机字符串 String echostr = request.getParameter("echostr"); PrintWriter out = response.getWriter(); // 通过检验 signature 对请求进行校验,若校验成功则原样返回 echostr,表示接入成功,否则接入失败 if(SignUtil.checkSignature(signature, timestamp, nonce)){ out.print(echostr); } out.close(); out = null;
代码中用到了
checkSignature 方法,该方法还没有实现,我们新建一个包 org.ivy.course.util 作为一个工具包,并往该包中添加新类 SignUtil,添加类的方法是:包名右键 -->new --> class,填上类名 SignUtil,其它默认,完整代码如下:
package org.ivy.course.util; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; public class SignUtil { /** * 与接口配置信息中的 token 要一致,这里赋予什么值,在接口配置信息中的Token就要填写什么值, * 两边保持一致即可,建议用项目名称、公司名称缩写等,我在这里用的是项目名称weixinface */ private static String token = "weixinface"; /** * 验证签名 * @param signature * @param timestamp * @param nonce * @return */ public static boolean checkSignature(String signature, String timestamp, String nonce){ String[] arr = new String[]{token, timestamp, nonce}; // 将 token, timestamp, nonce 三个参数进行字典排序 Arrays.sort(arr); StringBuilder content = new StringBuilder(); for(int i = 0; i < arr.length; i++){ content.append(arr[i]); } MessageDigest md = null; String tmpStr = null; try { md = MessageDigest.getInstance("SHA-1"); // 将三个参数字符串拼接成一个字符串进行 shal 加密 byte[] digest = md.digest(content.toString().getBytes()); tmpStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } content = null; // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()): false; } /** * 将字节数组转换为十六进制字符串 * @param digest * @return */ private static String byteToStr(byte[] digest) { // TODO Auto-generated method stub String strDigest = ""; for(int i = 0; i < digest.length; i++){ strDigest += byteToHexStr(digest[i]); } return strDigest; } /** * 将字节转换为十六进制字符串 * @param b * @return */ private static String byteToHexStr(byte b) { // TODO Auto-generated method stub char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; char[] tempArr = new char[2]; tempArr[0] = Digit[(b >>> 4) & 0X0F]; tempArr[1] = Digit[b & 0X0F]; String s = new String(tempArr); return s; } }
最后,看看代码,代码应该不会出错的了,但是,在类名 CoreServlet 上应该有个警告,根据编译器的提示,鼠标移到 CoreServlet 上,根据提示选择 add default serial Version ID 添加一个默认的 serialVersionUID。
到此,代码的编辑工作完成了,下一步就是打包部署了。
4、打包并提交到百度 BAE
工程右键打包一个 ROOT.war 包,名字必须是这个,保存地址建议保存到工程目录下,具体操作: 工程右键 --> Export --> Java EE --> WAR file,根据提示来操作保存。
到我们的 SVN 工作目录,新建一个文件夹,命名随意,例如 weixin0330,然后在文件夹上右键,选择 SVN CheckOut,填上 URL 地址,该地址可以到百度 BAE 上我们部署的应用中获得。
Checkout 出来默认版本号是 1:
进入CheckOut 的项目中,可以看到目录结构如下:
鼠标选中 ROOT.war 文件,右键 --> TortoiseSVN --> Delect,将该文件删除,删除后,文件夹会有一个感叹号,我们在文件夹 weixin0330 上:右键 --> SVN Commit --> OK,目的是将百度 BAE 上面的 ROOT.war 删除掉:
然后,我们回到 MyEclipse 的工作空间,将我们打包好的 ROOT.war 文件复制到 SVN 的工程目录下,复制进来的 ROOT.war 文件上会有个问号:
我们在文件 ROOT.war 上右键 --> TortoiseSVN --> add,此时问号变成加号,然后在文件夹 weixin0330 上:右键 --> SVN Commit --> OK,将我们最新的ROOT.war 提交到百度 BAE 。
然后回到百度 BAE 中查看我们的部署列表,会看到提示有“新版本” ,点击快捷发布。
然后点击查看,在弹出网页的网址后面添加web.xml 文件中 <url-pattern> 设定的值“ /servlet/CoreServlet” 并回车,会看到如下页面:
如果你看到了上述 500 画面说明你离成功只差一步了,记住复制此网页的地址备用。
5、成为微信开发者
打开微信公众平台 -> 高级功能 -> 开发者模式,见图:
将我们刚才复制的地址黏贴到 URL
;
在填写 Token 之前,回到我们的项目,在类 SignUtil 中有这么一句代码:
private static String token = "weixinface";
代码中的 token 的值我们可以随意写,但是,这里是什么值,在微信平台上就要填写对应的内容,所有,在
Token 那里填上 weixinface,点击“提交”,如果代码没有问题,瞬间你就可以看到“你已成为开发者” 的提示,如图 :
到此,所有的工作都已经完成,你可以不断丰富你的代码,实现不同的功能。你也可以在自己的微信中关注自己的订阅号,只需扫描公众平台的二维码就行了。
欢迎关注我的订阅号:天龙智能
二维码:
郑重声明:
本博客的代码是来自柳老师的博客( http://blog.csdn.net/column/details/wechatmp.html )我只是作为一种补充,我希望以此方式来表达我对柳老师的感谢之情,完全没有盗版之意,如有侵犯,请联系我,谢谢!