转载请标明出处,谢谢!
版本说明:
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
如果部署失败并提示警告,由于 bae 升级到 3.0 版本,实行分批制度,看百度网站公告,如果你没有拿到 BEA 资源,就无法继续进行操作。
成功部署后,是这样的:
3、新建项目
打开 MyEclipse ,新建一个 Web Project :
新建一个 servlet 包,方法是:"src" --> 右键 --> new --> packages, 命名随意,例如 org.ivy.course.servlet
通过向导往包里添加一个能够处理请求的Servlet 类,具体操作时包名右键 --> new --> Servlet:
- 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
)我只是作为一种补充,我希望以此方式来表达我对柳老师的感谢之情,完全没有盗版之意,如有侵犯,请联系我,谢谢