private String generateQrCode(String appId, String accessToken, String enterpriseId) {
Map<String, Object> params = new HashMap<>();
params.put("action_name", "QR_LIMIT_STR_SCENE");
Map<String, Object> actionInfo = new HashMap<>();
Map<String, Object> scene = new HashMap<>();
scene.put("scene_str", enterpriseId);
actionInfo.put("scene", scene);
params.put("action_info", actionInfo);
RestTemplate restTemplate = new RestTemplate();
String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + accessToken;
// 添加请求日志
log.info("生成二维码请求参数 - appId: {}, accessToken: {}, url: {}", appId, accessToken, url);
log.info("请求参数: {}", params);
try {
Map<String, Object> response = restTemplate.postForObject(url, params, Map.class);
// 添加响应日志
log.info("生成二维码响应结果: {}", response);
if (response != null && response.containsKey("ticket")) {
String ticket = (String) response.get("ticket");
String qrCodeUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + ticket;
log.info("成功生成二维码: {}", qrCodeUrl);
return qrCodeUrl;
} else {
log.error("生成二维码失败,响应中未包含ticket字段");
if (response != null && response.containsKey("errcode")) {
log.error("微信API错误 - errcode: {}, errmsg: {}", response.get("errcode"), response.get("errmsg"));
}
}
} catch (Exception e) {
log.error("生成二维码请求异常", e);
}
return null;
}
这里生成了带参数的二维码,扫码关注时会同步触发事件
@PostMapping("/{appId}/callback")
public String msgCallback(@PathVariable("appId") String appId,
@RequestParam(value = "signature", required = false) String signature,
@RequestParam(value = "timestamp", required = false) String timestamp,
@RequestParam(value = "nonce", required = false) String nonce,
@RequestParam(value = "encrypt_type", required = false) String encryptType,
@RequestParam(value = "msg_signature", required = false) String msgSignature,
@RequestBody(required = false) String requestBody) throws DocumentException {
log.info("=== 收到微信消息与事件推送 ===");
// POST请求 - 处理事件通知
log.info("收到POST请求,消息体: {}", requestBody);
// 检查密钥设置
String encodingAesKey = wechatConfig.getAesKey();
String token = wechatConfig.getToken();
String comappId = wechatConfig.getAppId();
log.info("encodingAesKey: {}", encodingAesKey);
log.info("token: {}", token);
log.info("comappId: {}", comappId);
// 解析 XML 消息
Map<String, String> msgMap = WxMessageUtils.parseXml(requestBody);
String encrypt = msgMap.get("Encrypt");
// 解密消息
String decryptedXml;
try {
WxBizMsgCrypt wxBizMsgCrypt = new WxBizMsgCrypt(token, encodingAesKey, comappId);
decryptedXml = wxBizMsgCrypt.decrypt(encrypt);
log.info("解密后的消息: {}", decryptedXml);
} catch (Exception e) {
log.error("消息解密失败, 密文: {}, 错误: {}", encrypt, e.getMessage());
return "success";
}
// 解析解密后的 XML 消息
msgMap = WxMessageUtils.parseXml(decryptedXml);
log.info("解析后的消息: {}", msgMap);
String msgType = msgMap.get("MsgType");
String event = msgMap.get("Event");
if ("event".equals(msgType) && "subscribe".equals(event)) {
// 处理关注事件
String openid = msgMap.get("FromUserName");
String eventKey = msgMap.get("EventKey");
log.info("收到关注事件 - openid: {}, eventKey: {}, raw message: {}",
openid, eventKey, decryptedXml);
if (eventKey != null && !eventKey.isEmpty()) {
String enterpriseId = eventKey.replace("qrscene_", "");
log.info("解析二维码参数 - 原始值: {}, 处理后: {}", eventKey, enterpriseId);
wechatWarnService.saveOpenidAndEnterpriseId(openid, enterpriseId);
}
} else if ("event".equals(msgType) && "SCAN".equals(event)) {
// 处理扫描二维码事件
String openid = msgMap.get("FromUserName");
String eventKey = msgMap.get("EventKey");
log.info("用户扫描二维码,openid: {}, eventKey: {}", openid, eventKey);
// TODO: 根据 eventKey 的值进行相应的处理,如果 eventKey 表示企业ID,可以调用 saveOpenidAndEnterpriseId 方法
}
return wxCallbackService.handleCallback(appId, signature, timestamp, nonce,
encryptType, msgSignature, requestBody);
}
现在问题是扫码点关注时后端 提示解密错误
09:22:49.551 [http-nio-8081-exec-94] DEBUG c.r.s.m.S.selectReadedList - [debug,135] - <== Total: 1
09:22:52.695 [http-nio-8081-exec-95] INFO c.r.w.c.WxCallbackController - [msgCallback,207] - === 收到微信消息与事件推送 ===
09:22:52.696 [http-nio-8081-exec-95] INFO c.r.w.c.WxCallbackController - [msgCallback,209] - 收到POST请求,消息体: <xml>
<ToUserName><![CDATA[gh_5ab73d995f8e]]></ToUserName>
<Encrypt><![CDATA[oPyM/kz3Ov78khziMZMhaPT6bZsrIXPGUhyP9xxG8Hg2OIbK2Xqv/PePVJKzyE2YaPZNCoJp57bSsQxN9eWynKy+r9uYMT7Qknp72mUzQCWhcmKn1nl8AsgTokHpAVoYHdffoab/9HqOOGuM2rHa+pr1pmn68u7r8qBCdTnxaL8HZ4BG54T7jUecLa4urZ+9CfDK3bbIZgbxdtw8xXjWFa+fTBvBIdI49F3YEgvfv0ImmbNe+h09mH5RrA8+nV1FOHhsvisHftUX9lvFiqEb92m7OflZIzGiog0sYwOMYW4RK7qlD0aIUQGm17A7t1M51QiO4a9w4ABrR0zMCsSbCyhwfK9HdIeo5dEPRqcPX7LjrKEFgsj+Go06RvtEbMSUm1GvTjMI9u6nJ11C67F16puVBlVgoMm7mq94603KzJMP2hBslwYDJCfjBKLTAzbmcbFHzrcaLb96bKe1lV6Mmm4r0miQg/oOdkxq1rW52Vp8rBs4pqRrlk1FqUDBiXmCW0I3N34Ow3UYqcF5Phyq+C2M7f0dHJ91yTosZsPOZbxHuvtgOi7xMBYR+kHK8nEKw0kjHEnNtQLOSeTl1m48ajTnnlN3sLPqUIp63ZGyEhZQGmBVHwu6Nu/Nv5H2zDry]]></Encrypt>
</xml>
09:22:52.696 [http-nio-8081-exec-95] INFO c.r.w.c.WxCallbackController - [msgCallback,215] - encodingAesKey: WxEncryptKey19345abcdef67890ghijkl12345mnxo
09:22:52.696 [http-nio-8081-exec-95] INFO c.r.w.c.WxCallbackController - [msgCallback,216] - token: WxcGeorge925811XwgE01B322115
09:22:52.696 [http-nio-8081-exec-95] INFO c.r.w.c.WxCallbackController - [msgCallback,217] - comappId: wxa7d1e80a0ba554c8
09:22:52.738 [http-nio-8081-exec-95] INFO c.r.w.u.WxBizMsgCrypt - [<init>,46] - AES密钥初始化成功, 长度: 32
09:22:52.739 [http-nio-8081-exec-95] INFO c.r.w.u.WxBizMsgCrypt - [decrypt,156] - Base64解码后的密文长度: 480
09:22:52.742 [http-nio-8081-exec-95] ERROR c.r.w.u.WxBizMsgCrypt - [decrypt,168] - 解密过程发生错误
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:989)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:845)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at com.ruoyi.wechatpublic.util.WxBizMsgCrypt.decrypt(WxBizMsgCrypt.java:159)
at com.ruoyi.wechatpublic.controller.WxCallbackController.msgCallback(WxCallbackController.java:227)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
如果是不通过二维码扫码关注没有这个问题是什么原因
你好,平台不会返回Java报错
名称:杭州市上城区跨次元文化创意工作室(个体商户)
统一社会信用代码92330102MAECK8928N
经营者彭佳曼