在使用前阅读官方文档:回调配置文档
分别是:URL, Token, EncodingAESKey。打开企业微信后台-->管理工具-->通讯录同步配置回调地址如下所示
1.1、URL为回调服务地址,由开发者搭建(直白点就是后台回调域名地址,你给企业微信的URL,例如http://127.0.0.1:8085/qiyewx/getCallBack)服务器如果是云服务要配置域名
1.2、Token用于计算签名,由英文或数字组成且长度不超过32位的自定义字符串。(可随机获取,但要复制到本地代码,后面会用到)
1.3、EncodingAESKey用于消息内容加密,由英文或数字组成且长度为43位的自定义字符串。(可随机获取,但要复制到本地代码,后面会用到)
# 企业微信配置 qiyewx: url: corpid: corpsecret: #回调配置 token: XXXXXX encodingAESKey: XXXXXX
有json版本和xml版本
json版本:
xml版本:
加解密库下载与返回码 - 接口文档 - 企业微信开发者中心
commons-codec commons-codecorg.json json20200518 dom4j dom4j1.6.1
切记:将将下载的示例代码复制到你的项目代码中,下面的代码中有使用。
/** * 企业微信回调 * 3.1 支持Http Get请求验证URL有效性 * 3.2 支持Http Post请求接收业务数据 * * @return */ @RequestMapping(value = "/getCallBack", method = {RequestMethod.GET, RequestMethod.POST}) public Object CompanyWeChatChangeNotice(HttpServletRequest request, @RequestBody(required = false) String body) { MapparameterMap = request.getParameterMap(); String jsonString = JSONObject.toJSONString(parameterMap); log.info("企业微信回调参数:{}, 解析参数:{}", jsonString, body); if (body == null) { Object result = qyWxService.verificationUrl(request); return result; } Map resultMap = qyWxService.getRequestParameter(request, body); System.err.println(resultMap); return "success"; }
/** * 验证回调URL * * @param request * @return */ public Object verificationUrl(HttpServletRequest request) { log.info("=========验证URL有效性开始========="); String sEchoStr; //需要返回的明文 try { WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(qyWxConfig.getToken(), qyWxConfig.getEncodingAESKey(), qyWxConfig.getCorpid()); String msgSignature = request.getParameter("msg_signature"); String timeStamp = request.getParameter("timestamp"); String nonce = request.getParameter("nonce"); String echostr = request.getParameter("echostr"); log.info("企业微信加密签名: {},时间戳: {},随机数: {},加密的字符串: {}", msgSignature, timeStamp, nonce, echostr); sEchoStr = wxcpt.VerifyURL(msgSignature, timeStamp, nonce, echostr); log.info("给企业微信返回的明文,{}", sEchoStr); log.info("=========验证URL有效性结束========="); return sEchoStr; } catch (AesException e) { log.error("验证URL失败,错误原因请查看异常:{}", e.getCode()); throw new AesException(e.getCode()); } }
/** * 企业微信回调参数解析 * * @param request * @param body * @return */ public MapgetRequestParameter(HttpServletRequest request, String body) { log.info("=========参数解析开始========="); try { WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(qyWxConfig.getToken(), qyWxConfig.getEncodingAESKey(), qyWxConfig.getCorpid()); String msgSignature = request.getParameter("msg_signature"); String timeStamp = request.getParameter("timestamp"); String nonce = request.getParameter("nonce"); log.info("企业微信加密签名: {},时间戳: {},随机数: {}", msgSignature, timeStamp, nonce); String sMsg = wxcpt.DecryptMsg(msgSignature, timeStamp, nonce, body); Map resultMap = new HashMap (16); resultMap = ConstantUtil.parseXmlToMap(sMsg, resultMap); log.info("decrypt密文转为map结果为{}", resultMap); log.info("=========参数解析结束========="); return resultMap; } catch (AesException e) { log.error("密文参数解析失败,错误原因请查看异常:{}", e.getMessage()); throw new AesException(e.getCode()); } }
package com.ruoyi.system.qiwechat.utils; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import java.io.StringReader; import java.util.Iterator; import java.util.Map; /** * @author XiYuan * @date 2023/2/20 * @Description: XML转换Map */ public class ConstantUtil { /** * 将xml转换为Map。 支持xml标签多层嵌套,并以"."分隔多级标签(不包括根节点)。 不支持XML标签重复时的情况 * * @param xml * @param map * @return */ public static MapparseXmlToMap(String xml, Map map) { try { SAXReader reader = new SAXReader(); Document doc = reader.read(new StringReader(xml)); Element root = doc.getRootElement(); String path = ""; if (map.containsKey(root.getName().trim())) { path = map.get(root.getName().trim()); map.remove(root.getName().trim()); } for (Iterator i = root.elementIterator(); i.hasNext();) { Element element = (Element) i.next(); if (element.isTextOnly()) { if (path.length() > 0) { map.put(path + element.getName().trim(), element.getTextTrim()); } else { map.put(element.getName().trim(), element.getTextTrim()); } } else { map.put(element.getName().trim(), path+ element.getName().trim() + "."); parseXmlToMap(element.asXML(), map); } } } catch (Exception e) { e.printStackTrace(); } return map; } }
package com.ruoyi.common.config; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @Data @Configuration public class QyWxConfig { /** * 请求路径 */ @Value("${qiyewx.url}") private String url; /** * 企业微信ID */ @Value("${qiyewx.corpid}") private String corpid; /** * 企业应用的凭证密钥 */ @Value("${qiyewx.corpsecret}") private String corpsecret; /** * 开发者设置的token */ @Value("${qiyewx.token}") private String token; /** * 开发者设置的EncodingAESKey */ @Value("${qiyewx.encodingAESKey}") private String encodingAESKey; }
企业微信开发者中心测试工具
所要参数依次写入,测试
如下红框所示:
备注:要根据事件的类型Event判断回调的事件,在回调事件中根据ChangeType判断事件性质
看完有所帮助请点点赞,送人玫瑰,手留余香。给作者一个👍🏻