在使用前阅读官方文档:回调配置文档
分别是: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-codec
org.json
json
20200518
dom4j
dom4j
1.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) {
Map parameterMap = 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 Map getRequestParameter(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 Map parseXmlToMap(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判断事件性质


看完有所帮助请点点赞,送人玫瑰,手留余香。给作者一个👍🏻