大家好,我是小悟
在做微信小程序或公众号开发的有时候,难免会遇到需要在用户关注或取关公众号后处理业务逻辑的需求,只需要几步就可以搞定。
(相关资料图)
1、配置
首先我们需要在微信公众号后台进行服务器配置,登录公众号后台->开发->基本配置->服务器配置,如下:
服务器地址就是我们写的一个controller(代码在下面),用来给微信校验,和接收微信发过来的消息,如果地址错误或者token错误,提交信息的时候会报错
SignUtil
/** * @description */public class SignUtil { /** * 验证签名 * @param token * @param signature 签名用来核实最后的结果是否一致 * @param timestamp 时间标记 * @param nonce 随机数字标记 * @return 一个布尔值确定最后加密得到的是否与signature一致 */ public static boolean checkSignature(String token, String signature, String timestamp, String nonce) { //将传入参数变成一个String数组然后进行字典排序 String[] arr = new String[] { token, timestamp, nonce }; // 将token、timestamp、nonce三个参数进行字典排序 Arrays.sort(arr); //创建一个对象储存排序后三个String的结合体 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"); 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 */ 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 */ 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; }}
MsgUtil
/** * @description */public class MsgUtil { public static final String MSGTYPE_EVENT = "event";//消息类型--事件 public static final String MESSAGE_SUBSCIBE = "subscribe";//消息事件类型--订阅事件 public static final String MESSAGE_UNSUBSCIBE = "unsubscribe";//消息事件类型--取消订阅事件 public static final String MESSAGE_TEXT = "text";//消息类型--文本消息 /** * 组装文本消息 */ public static String textMsg(String toUserName,String fromUserName,String content){ TextMsg text = new TextMsg(); text.setFromUserName(toUserName); text.setToUserName(fromUserName); text.setMsgType(MESSAGE_TEXT); text.setCreateTime(new Date().getTime()); text.setContent(content); return XmlUtil.textMsgToxml(text); } /** * 响应订阅事件--回复文本消息 */ public static String subscribeForText(String toUserName,String fromUserName,String content){ return textMsg(toUserName, fromUserName, content); } /** * 响应取消订阅事件 */ public static String unsubscribeForText(String toUserName,String fromUserName,String content){ System.out.println("用户:"+ fromUserName +"取消关注~"); return ""; }}
application.yml
parameter: #微信公众号 publicAppId: 微信公众号AppId publicAppSecret: 微信公众号AppSecret
WxPublicController
/** * @description */@Controller@RequestMapping(value = "/message/weixin")public class WxPublicController { protected static Logger logger = LoggerFactory.getLogger(WxPublicController.class); //填写和公众号后台配置的一样的token private static final String TOKENN = ""; /** * 微信公众号appId */ @Value("${parameter.publicAppId}") private String publicAppId; /** * 微信公众号appSecret */ @Value("${parameter.publicAppSecret}") private String publicAppSecret; @RequestMapping(method = RequestMethod.GET) public void get(HttpServletRequest request, HttpServletResponse response) { // 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 String signature = request.getParameter("signature"); // 时间戳 String timestamp = request.getParameter("timestamp"); // 随机数 String nonce = request.getParameter("nonce"); // 随机字符串 String echostr = request.getParameter("echostr"); PrintWriter out = null; try { out = response.getWriter(); // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,否则接入失败 if (SignUtil.checkSignature(TOKENN, signature, timestamp, nonce)) { out.print(echostr); } } catch (IOException e) { e.printStackTrace(); } finally { if (out != null ) { out.close(); } } } @RequestMapping(method = RequestMethod.POST) public void post(HttpServletRequest request, HttpServletResponse response) { // 响应消息 PrintWriter out = null; String resMessage = ""; try { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); //把微信返回的xml信息转义成map Map map = XmlUtil.parseXml(request); //消息来源用户标识 String fromUserName = map.get("FromUserName"); //消息目的用户标识 String toUserName = map.get("ToUserName"); //消息创建时间(整型) String createTime = map.get("CreateTime"); //消息类型 String msgType = map.get("MsgType"); //事件类型:subscribe/unsubscribe String eventType = map.get("Event"); //如果为事件类型 if(MsgUtil.MSGTYPE_EVENT.equals(msgType)){ //处理订阅事件 if(MsgUtil.MESSAGE_SUBSCIBE.equals(eventType)){ resMessage = MsgUtil.subscribeForText(toUserName, fromUserName, "您好,谢谢您的关注!!!"); //TODO 业务逻辑 //处理取消订阅消息 } else if(MsgUtil.MESSAGE_UNSUBSCIBE.equals(eventType)) { //TODO 业务逻辑 } logger.info("eventType:"+eventType+",fromUserName:"+fromUserName+",toUserName:"+toUserName+",msgType:"+msgType+",createTime:"+createTime); } out = response.getWriter(); out.println(resMessage); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { if (out != null ) { out.close(); } } }}
您的一键三连,是我更新的最大动力,谢谢
山水有相逢,来日皆可期,谢谢阅读,我们再会
我手中的金箍棒,上能通天,下能探海
上一篇:微信小程序模板消息接口下线了,不用慌,调用统一服务消息接口来实现相同功能
关键词: