赞
踩
第一步:请求校验(确认请求来自微信服务器)
代码如下:
@ApiOperation(value = " 微信消息通知-请求校验(确认请求来自微信服务器)") @RequestMapping(value = "/signature") public String signature(HttpServletRequest request, HttpServletResponse response) { if (request.getMethod().equals("GET")) { //微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数 String signature = request.getParameter("signature"); // 时间戳 String timestamp = request.getParameter("timestamp"); // 随机数 String nonce = request.getParameter("nonce"); // 随机字符串 String echostr = request.getParameter("echostr"); log.info("echostr>>>>>>>>>>" + echostr); //通过检验signature对请求进行校验,若校验成功则原样返回echostr,否则接入失败 if (checkSignature(signature, timestamp, nonce)) { log.info("echostr>>>>>>>>>>>>" + echostr); return echostr; } log.info("客服消息验证url验证结果:{}", echostr); }
checkSignature()方法如下:
/** * 校验(确认请求来自微信服务器) * * @param signature * @param timestamp * @param nonce * @return */ public boolean checkSignature(String signature, String timestamp, String nonce) { String[] params = { aliProperties.getAccessToken(), timestamp, nonce}; log.info("params>>>>>>>>>>>>>" + params); //1、将token、timestamp、nonce三个参数进行字典序排序 Arrays.sort(params); //2、将三个参数字符串拼接成一个字符串 StringBuilder sb = new StringBuilder(); for (String param : params) { sb.append(param); } log.info("字符串拼接>>>>>>>>>>>>>>>>>" + sb); MessageDigest md = null; String tpmStr = null; try { md = MessageDigest.getInstance("SHA-1"); log.info("md>>>>>>>>>>>>" + md); //3、将三个参数字符串拼接成一个字符串进行sha1加密 byte[] digest = md.digest(sb.toString().getBytes()); log.info("digest>>>>>>>>>>>" + digest); tpmStr = StringUtil.byteToHex(digest); log.info("加密串>>>>>>>>>>>" + tpmStr); } catch (Exception e) { log.info("错误信息>>>>>>>>>>>>" + e.getMessage()); e.printStackTrace(); } //4、将sha1加密后的字符串可与signature对比,标识该请求来源于微信 return tpmStr != null && tpmStr.equals(signature); }
上面代码就是做的第一步,校验。根据小程序对接文档可知,校验时为GET请求(一定)。
第二步:对接小程序客服功能
代码如下:
else { try { // 接收消息并返回消息 String result = acceptMessage(request, response); log.info("接受消息并返回消息result>>>>>>" + result); // 响应消息 PrintWriter out = response.getWriter(); log.info("out>>>>>>>>" + out); out.print(result); out.close(); } catch (Exception ex) { log.error("微信帐号接口配置失败!" + ex.getMessage()); ex.printStackTrace(); } } return null; }
这里的else是连在上面if后面的(因为对接小程序,只能写在一个接口中,校验时是GET,对接时是POST,所以if为校验,else才为真正对接类容)
acceptMessage()方法
public String acceptMessage(HttpServletRequest request, HttpServletResponse response) { //返回值 String result = "success"; try { // 将请求、响应的编码均设置为UTF-8(防止中文乱码) request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); Map<String, String> requestMap = MessageUtil.parseXml(request); log.info("requestMap>>>>>>>>>>" + requestMap); // 发送者的openid String fromUserName = requestMap.get("FromUserName"); // 小程序的原始ID String toUserName = requestMap.get("ToUserName"); // 消息类型 String msgType = requestMap.get("MsgType"); // 文本消息内容 String content = requestMap.get("Content"); // 事件类型 String event = requestMap.get("Event"); log.info("fromUserName=" + fromUserName + ",toUserName=" + toUserName + ",msgType=" + msgType + ",content=" + content + ",event=" + event); StringBuffer contentMessage = new StringBuffer(); if (msgType.equals("event")) { contentMessage.append("欢迎进入XXX客服咨询!人工服务请输入0").append("\n"); log.info(sendCustomerTextMessage(fromUserName, contentMessage.toString(), wxXCXTempSendUtil.getToken())); } else if (msgType.equals("text")) { //文本消息 if (content.equals("0")) { return switchCustomerService(fromUserName, toUserName); } else { contentMessage.append("欢迎进入XXX客服咨询!人工服务请输入0").append("\n"); log.info(sendCustomerTextMessage(fromUserName, contentMessage.toString(), wxXCXTempSendUtil.getToken())); } } else { contentMessage.append("欢迎进入XXX客服咨询!人工服务请输入0").append("\n"); log.info(sendCustomerTextMessage(fromUserName, contentMessage.toString(), wxXCXTempSendUtil.getToken())); } } catch (Exception e) { log.info("错误信息打印>>>>>>>>>>>" + e.getMessage()); e.printStackTrace(); } return result; }
switchCustomerService()方法:
小程序对接人工服务的返回固定数据结构
/** * 人工服务 * * @param fromUserName * @param toUserName * @param requestMap * @return */ public String switchCustomerService(String fromUserName, String toUserName) { String returnXml = "<xml>\n" + " <ToUserName><![CDATA[" + fromUserName + "]]></ToUserName>\n" + " <FromUserName><![CDATA[" + toUserName + "]]></FromUserName>\n" + " <CreateTime>" + System.currentTimeMillis() / 1000 + "</CreateTime>\n" + " <MsgType><![CDATA[transfer_customer_service]]></MsgType>\n" + "</xml>"; log.info("人工服务result>>>>>>>" + returnXml); return returnXml; }
sendCustomerTextMessage()方法:
文本消息返回固定数据结构
/** * 文本消息 * * @param openid * @param text * @param accessToken * @return */ private static String SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/custom/send";//固定发送地址 public String sendCustomerTextMessage(String openid, String text, String accessToken) throws IOException { HashMap<String, Object> map_content = new HashMap<>(); map_content.put("content", text); HashMap<String, Object> map = new HashMap<>(); map.put("touser", openid); map.put("msgtype", "text"); map.put("text", map_content); String content = JSON.toJSONString(map); log.info("文本消息content" + content); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity httpEntity
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。