结论
如果你的公网接口是正常的,直接返回echostr也会校验失败!那么肯定是返回值不对!!!
返回值必须为整数,不能为字符串,微信服务器可接收的数据类型是:content-type: text/html; charset=utf-8
@RequestMapping(value = "/validate", produces = "text/plain;charset=UTF-8")
public Long validate(String signature, String timestamp, String nonce, String echostr, HttpServletResponse response) {
return wechatService.validate(signature, timestamp, nonce, echostr);
}
代码
@RequestMapping("/wechat")
@RestController
public class WechatController {
@Resource
private WechatService wechatService;
/**
* 接口配置信息验证,返回值一定要是Long,不能为String
*
* @param signature 签名
* @param timestamp 时间戳
* @param nonce nonce
* @param echostr echostr
* @param response 回答
* @return {@link Long }
* @author huxp
*/
@RequestMapping(value = "/validate", produces = "text/plain;charset=UTF-8")
public Long validate(String signature, String timestamp, String nonce, String echostr, HttpServletResponse response) {
return wechatService.validate(signature, timestamp, nonce, echostr);
}
}
@Slf4j
@Service
public class WechatServiceImpl implements WechatService {
public static final String weChatToken = "xxxxxx";
public static final String weChatAppId = "xxxxxxxxx";
public static final String weChatAppSecret = "xxxxxxxxxxx";
/**
* 验证消息来自微信服务器
*
* @param signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
* @param timestamp 时间戳
* @param nonce 随机数
* @param echostr 随机字符串
* @return 随机字符串
*/
@Override
public Long validate(String signature, String timestamp, String nonce, String echostr) {
//获取参数配置
log.info("signature: {}, timestamp: {}, nonce: {}, echostr: {}", signature, timestamp, nonce, echostr);
String[] arrTmp = {weChatToken, timestamp, nonce};
Arrays.sort(arrTmp);
StringBuilder sb = new StringBuilder();
for (String s : arrTmp) {
sb.append(s);
}
try {
String sha1Hex = DigestUtils.sha1Hex(sb.toString());
log.info("sha1Hex: {}", sha1Hex);
log.info("signature: {}", signature);
//获取消息对象
if (signature.contentEquals(sha1Hex)) {
return Long.parseLong(echostr.trim());
}
} catch (Exception e) {
log.error("校验失败: ", e);
}
return null;
}
}