一,接入微信公众号
接入微信公众号时,第一步需要配置相关信息(url,token等),然后要验证服务器地址的有效性. 参考文档: 点击打开链接
这里主要介绍服务器端地址的验证.
二, 服务器端代码
2.1 SignUtil.java 签名工具类
package com.junlenet.core.weixin.util; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; /** * 签名认证工具类 * @author Weijun Hu * @since 2016年7月9日 上午10:19:36 */ public class SignUtil { /** * 加密/校验流程如下: <li>1. 将token、timestamp、nonce三个参数进行字典序排序</li> <li>2. 将三个参数字符串拼接成一个字符串进行sha1加密</li> <li>3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信</li> * @param token * @param signature * @param timestamp * @param nonce * @return * @date 2016年7月9日 上午10:19:36 * @url http://mp.weixin.qq.com/wiki/17/2d4265491f12608cd170a95559800f2d.html */ public static boolean checkSignature(String token, 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"); // 将三个参数字符串拼接成一个字符串进行sha1加密 byte[] digest = md.digest(content.toString().getBytes()); tmpStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } content = null; // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false; } /** * 将字节数组转换为十六进制字符串 * @param byteArray * @return * @date 2016年7月9日 上午10:20:53 */ private static String byteToStr(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexStr(byteArray[i]); } return strDigest; } /** * 将字节转换为十六进制字符串 * @param mByte * @return * @date 2016年7月9日 上午10:20:59 */ private static String byteToHexStr(byte mByte) { 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[(mByte >>> 4) & 0X0F]; tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr); return s; } }
2.2 WechatController.java 微信Controller类
package com.junlenet.core.weixin.controller; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.junlenet.core.weixin.util.SignUtil; /** * 微信控制器 * @author Weijun Hu * @since 2016年7月9日 上午10:19:36 */ @Controller @RequestMapping("/wechatController") public class WechatController { /** * 微信公众号: 验证服务器地址的有效性<br> * 微信URL: http://IP:PORT/项目名称/wechatController/wechat.do<br> * 开发者通过检验signature对请求进行校验。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。<br> * 参考api: http://mp.weixin.qq.com/wiki/17/2d4265491f12608cd170a95559800f2d.html * @param request * @param response * @param signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 * @param timestamp 时间戳 * @param nonce 随机数 * @param echostr 随机字符串 * @date 2016年7月9日 上午11:10:30 */ @RequestMapping(value="wechat", method = RequestMethod.GET) public void wechat(HttpServletRequest request,HttpServletResponse response,String signature,String timestamp,String nonce,String echostr) { String token = "XXXXXXXXXXXXXXXXXXXXXXXX";//配置里面的token boolean flag = SignUtil.checkSignature(token, signature, timestamp, nonce); if(flag){ try { //验证成功,则原样返回echostr参数内容 response.getWriter().print(echostr); } catch (Exception e) { e.printStackTrace(); } } } /** * 消息处理 * @param response * @param request * @throws IOException * @date 2016年7月9日 上午11:20:31 */ @RequestMapping(value = "wechat", method = RequestMethod.POST) public void wechatPost(HttpServletResponse response,HttpServletRequest request) throws IOException { /*String respMessage = wechatService.do(request);*/ //TODO 处理相关业务 PrintWriter out = response.getWriter(); //out.print(respMessage); out.close(); } }
附件: 微信公众号服务端配置图片.