标题微信的回调消息
业务用到了微信的回调,就是动态二维码,别人扫了关注公众号之后会给服务器进行发送消息,包括普通的关注,取消关注也会消息发送,微信对话等,都会转发到自定义的服务器
- 在微信公众号的基本设置,服务器配置设置url,启动之前就需要验证,开始启用之后会调用服务器接口
服务器需要专门一个接口来处理微信消息,验证参数,正确的才会进行处理,这个接口不能有任何权限限制,应该为都可以访问,但是接口内部对接口参数进行验证
@RequestMapping(value = "/dealMessage", produces = "application/xml;charset=UTF-8")
public void dealMessage(HttpServletRequest request, HttpServletResponse response) throws Exception {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//获取微信请求参数
String signature = request.getParameter ("signature");
String timestamp = request.getParameter ("timestamp");
String nonce = request.getParameter ("nonce");
String echostr = request.getParameter ("echostr");
log.info("接收微信公众号事件触发回调请求:\n signature:{}\ntimestamp:{}\nnonce:{}\nechostr:{}",signature,timestamp,nonce,echostr);
//参数排序。 token 就要换成自己实际写的 token
String [] params = new String [] {timestamp,nonce,"508c503fa024cc5fdac8c0b4"} ;
Arrays.sort (params) ;
//拼接
String paramstr = params[0] + params[1] + params[2] ;
log.info("重新参数拼接,paramstr:{}",paramstr);
//加密
//获取 shal 算法封装类
MessageDigest Sha1Dtgest = MessageDigest.getInstance("SHA-1") ;
//进行加密
byte [] digestResult = Sha1Dtgest.digest(paramstr.getBytes (StandardCharsets.UTF_8));
//这里需要将字节数组转16进制(我是用了工具类)
String mysignature = byte2HexStr(digestResult);
log.info("微信加密,signature:{}\n本地加密结果,mysignature:{}",signature,mysignature);
//是否正确
boolean signsuccess = mysignature.equals(signature);
if (!signsuccess) {
log.info("验证失败,signature check fail");
//不正确就直接返回失败提示.
out.println( "signature check fail");
}
log.info("验证成功,echostr:"+echostr);
// 可以在这里处理逻辑
log.info(" 接收微信返回信息 {} ", request.getInputStream().toString());
// 处理xml数据
Map<String, String> xmlData = RequestParamTool.getXmlData(request.getInputStream());
log.info("接收到的参数xmlData:=============={}",xmlData);
//业务处理
String responseString = dealWeChatIncoiceService.dealBean2XmlForBuild(xmlData,out);
log.info("responseString:{}",responseString);
//判断 echostr 不为空,表示这是配置时的请求。
if ( !StringUtils.isEmpty(echostr)) {
out.println(echostr);
//正确,返回传入的随机字符串。
}
}