3.2.3 请求校验流程分析
在Java中,处理HTTP GET请求就需要用到Servlet(当然也可以使用JSP或者Struts,但JSP和Struts本质上也是Servlet),在Servlet中接收参数signature、timestamp、nonce和echostr的代码如下所示:
- String signature = request.getParameter("signature");
- String timestamp = request.getParameter("timestamp");
- String nonce = request.getParameter("nonce");
- String echostr = request.getParameter("echostr");
要对token、timestamp和nonce3个参数按字典排序,可以使用java.util.Arrays类的sort()方法;而将排序后的结果拼接成一个字符串,可以使用String类的contat()方法。实现代码如下:
- // 对token、timestamp和nonce按字典排序
- String[] paramArr = new String[] { token, timestamp, nonce };
- Arrays.sort(paramArr);
- // 将排序后的结果拼接成一个字符串
- String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);
对拼接后的字符串content进行sha1加密可以使用java.security.MessageDigest类来实现,代码如下:
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- // 对拼接后的字符串进行sha1加密
- byte[] digest = md.digest(content.getBytes());
可以看到,进行sha1加密后的结果是一个byte数组,而我们需要的是一个字符串。所以,还需要通过下面的方法将byte数组转换成字符串:
- /**
- * 将字节数组转换为十六进制字符串
- *
- * @param bytearray
- * @return
- */
- private static String byteToStr(byte[] bytearray) {
- String strDigest = "";
- for (int i = 0; i < bytearray.length; i++) {
- strDigest += byteToHexStr(bytearray[i]);
- }
- return strDigest;
- }
- /**
- * 将字节转换为十六进制字符串
- *
- * @param ib
- * @return
- */
- private static String byteToHexStr(byte ib) {
- char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
- 'C', 'D', 'E', 'F' };
- char[] ob = new char[2];
- ob[0] = Digit[(ib >>> 4) & 0X0F];
- ob[1] = Digit[ib & 0X0F];
- String s = new String(ob);
- return s;
- }
调用上面的byteToStr()方法将sha1加密后的byte数组转换成字符串,如下所示:
- String ciphertext = byteToStr(digest);
最后,还要将字符串ciphertext与参数signature进行比较,如果相等,则将参数echostr原样返回。实现代码如下:
- PrintWriter out = response.getWriter();
- // 请求校验,若校验成功则原样返回echostr
- if (ciphertext.equals(signature.toUpperCase())) {
- out.print(echostr);
- }
- out.close();