创建一个Java Web工程,命名任意, 代码如下
1 package com.javen.course.servlet; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse;10 11 import com.javen.course.service.CrazyService;12 import com.javen.course.util.SignUtil;13 14 /**15 * 核心请求处理类 16 * @author 简爱微萌17 * @Email zyw205@gmail.com18 * 19 */20 public class CrazyServlet extends HttpServlet {21 22 private static final long serialVersionUID = -5021188348833856475L;23 @Override24 protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {25 // 微信加密签名 26 String signature = request.getParameter("signature"); 27 // 时间戳 28 String timestamp = request.getParameter("timestamp"); 29 // 随机数 30 String nonce = request.getParameter("nonce"); 31 // 随机字符串 32 String echostr = request.getParameter("echostr"); 33 PrintWriter out = response.getWriter(); 34 // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 35 if (SignUtil.checkSignature(signature, timestamp, nonce)) { 36 out.print(echostr); 37 } 38 out.close();39 out = null;40 }41 42 43 @Override44 protected void doPost(HttpServletRequest request, HttpServletResponse response)45 throws ServletException, IOException {46 // TODO 消息的接收、处理、响应 47 }48 }
代码中只完成了doGet方法,它的作用正是确认请求是否来自于微信服务器;而doPost方法这里验证不需要我们先放着。
在doGet方法中调用了SignUtil.java 实现代码如下 1 package com.javen.course.util;
1 package com.javen.course.util; 2 3 import java.security.MessageDigest; 4 import java.security.NoSuchAlgorithmException; 5 import java.util.Arrays; 6 7 /** 8 * 请求校验工具类 9 * 10 * @author 简爱微萌11 * @Email zyw205@gmial.com12 * 13 */14 public class SignUtil {15 // 与接口配置信息中的Token要一致16 private static String token = "Javen";17 18 /**19 * 验证签名20 * 21 * @param signature22 * @param timestamp23 * @param nonce24 * @return25 */26 public static boolean checkSignature(String signature, String timestamp,27 String nonce) {28 String[] arr = new String[] { token, timestamp, nonce };29 // 将token、timestamp、nonce三个参数进行字典序排序30 //Arrays.sort(arr);31 sort(arr);32 StringBuilder content = new StringBuilder();33 for (int i = 0; i < arr.length; i++) {34 content.append(arr[i]);35 }36 MessageDigest md = null;37 String tmpStr = null;38 39 try {40 md = MessageDigest.getInstance("SHA-1");41 // 将三个参数字符串拼接成一个字符串进行sha1加密42 byte[] digest = md.digest(content.toString().getBytes());43 tmpStr = byteToStr(digest);44 } catch (NoSuchAlgorithmException e) {45 e.printStackTrace();46 }47 48 content = null;49 // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信50 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;51 }52 53 /**54 * 将字节数组转换为十六进制字符串55 * 56 * @param byteArray57 * @return58 */59 private static String byteToStr(byte[] byteArray) {60 String strDigest = "";61 for (int i = 0; i < byteArray.length; i++) {62 strDigest += byteToHexStr(byteArray[i]);63 }64 return strDigest;65 }66 67 /**68 * 将字节转换为十六进制字符串69 * 70 * @param mByte71 * @return72 */73 private static String byteToHexStr(byte mByte) {74 char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',75 'B', 'C', 'D', 'E', 'F' };76 char[] tempArr = new char[2];77 tempArr[0] = Digit[(mByte >>> 4) & 0X0F];78 tempArr[1] = Digit[mByte & 0X0F];79 80 String s = new String(tempArr);81 return s;82 }83 84 public static void sort(String a[]) {85 for (int i = 0; i < a.length - 1; i++) {86 for (int j = i + 1; j < a.length; j++) {87 if (a[j].compareTo(a[i]) < 0) {88 String temp = a[i];89 a[i] = a[j];90 a[j] = temp;91 }92 }93 }94 }95 }
注意:SignUtil类中的成员变量token,这里赋予什么值,在接口配置信息中的Token就要填写什么值,两边要保持一致
最后再来看一下CoreServlet是怎么配置的,web.xml中的配置代码如下:
1 23 4 5 15 16CrazyServlet 67 com.javen.course.servlet.CrazyServlet 8 917 20 24CrazyServlet 18/Javen 1925 27index.jsp 26
到目前为止,所有编码都完成了,就是这么简单。接下来就是将工程发布到公网服务器上,如果没有公网服务器环境,可以去了解下BAE、SAE或者租赁一个服务器。发布到服务器上后,我们在浏览器里访http://你服务器的Ip或者域名/Javen(项目名)/Javen,如果看到如下界面就表示我们的代码没有问题:
PS:在浏览器中直接访问就相当于提交的是GET请求,而我们什么参数都没有传,在验证的时候当然会报空指针异常。
最好在功能>>高级功能>>开发模式中填写对应的URL和Token即可 没有找到页面的可以参考