3.2.3 请求校验流程分析

在Java中,处理HTTP GET请求就需要用到Servlet(当然也可以使用JSP或者Struts,但JSP和Struts本质上也是Servlet),在Servlet中接收参数signature、timestamp、nonce和echostr的代码如下所示:

  1. String signature = request.getParameter("signature");
  2. String timestamp = request.getParameter("timestamp");
  3. String nonce = request.getParameter("nonce");
  4. String echostr = request.getParameter("echostr");

要对token、timestamp和nonce3个参数按字典排序,可以使用java.util.Arrays类的sort()方法;而将排序后的结果拼接成一个字符串,可以使用String类的contat()方法。实现代码如下:

  1. // 对token、timestamp和nonce按字典排序
  2. String[] paramArr = new String[] { token, timestamp, nonce };
  3. Arrays.sort(paramArr);
  4.  
  5. // 将排序后的结果拼接成一个字符串
  6. String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);

对拼接后的字符串content进行sha1加密可以使用java.security.MessageDigest类来实现,代码如下:

  1. MessageDigest md = MessageDigest.getInstance("SHA-1");
  2. // 对拼接后的字符串进行sha1加密
  3. byte[] digest = md.digest(content.getBytes());

可以看到,进行sha1加密后的结果是一个byte数组,而我们需要的是一个字符串。所以,还需要通过下面的方法将byte数组转换成字符串:

  1. /**
  2. * 将字节数组转换为十六进制字符串
  3. *
  4. * @param bytearray
  5. * @return
  6. */
  7. private static String byteToStr(byte[] bytearray) {
  8. String strDigest = "";
  9. for (int i = 0; i < bytearray.length; i++) {
  10. strDigest += byteToHexStr(bytearray[i]);
  11. }
  12. return strDigest;
  13. }
  14.  
  15. /**
  16. * 将字节转换为十六进制字符串
  17. *
  18. * @param ib
  19. * @return
  20. */
  21. private static String byteToHexStr(byte ib) {
  22. char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
  23. 'C', 'D', 'E', 'F' };
  24. char[] ob = new char[2];
  25. ob[0] = Digit[(ib >>> 4) & 0X0F];
  26. ob[1] = Digit[ib & 0X0F];
  27.  
  28. String s = new String(ob);
  29. return s;
  30. }

调用上面的byteToStr()方法将sha1加密后的byte数组转换成字符串,如下所示:

  1. String ciphertext = byteToStr(digest);

最后,还要将字符串ciphertext与参数signature进行比较,如果相等,则将参数echostr原样返回。实现代码如下:

  1. PrintWriter out = response.getWriter();
  2. // 请求校验,若校验成功则原样返回echostr
  3. if (ciphertext.equals(signature.toUpperCase())) {
  4.  out.print(echostr);
  5. }
  6. out.close();