问题描述
问题导致的源头:{"errcode":42001,"errmsg":"access_token expired hint: [8W2pha0008vr 72!]"}
这个提示意思是说token失效了,为什么会失效,因为在服务器上面也有一个获取token的线程,而我本地测试也在获取token,相互覆盖了。我本地代码实现的逻辑是:第一次拿到token就放入缓存,设置有效期1小时,在这1小时内都去redis中取。这时候如果其他地方也用同样的APPID和APPSECRET去获取token,那我这里redis里面的不就失效了,再用它去请求其他数据就会返回上面这个json。
而我对于返回错误码的处理是返回一个空对象,并没有尝试重新获取;
问题解决
问题解决的最直接方案当然就是增加一个机制,判断这个错误码,并尝试重新获取token,并刷新缓存。
问题的引申
这里引申出来另外一个问题,记录一下。这个问题是因为我没有对不同的APPID进行区分导致的。
举个例子:假设微信的access_token在redis中的key是wechat_token,每次使用都会去取,如果这时候我换了另外一个APPID,但是token还是使用这个,岂不是GG。下次记得这种情况一定要进行区分(wechat_token+":"+APPID)
微信公众号的二维码,有效期内生成的URL是否会覆盖之前的?
经过测试是不会的,在有效期内连续请求生成二维码两次,拿到的两个链接在期限时间内都是可以使用的。
测试代码:
private static String QRCODE_CREATE_URL = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";
private static String QRCODE_GET_URL = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";
public static String getQrCodeUrl(String access_token) {
String qrCodeCreateUrl = QRCODE_CREATE_URL.replace("TOKEN", access_token);
//{"expire_seconds": 604800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 123}}}
JSONObject qrJsonObj = new JSONObject();
qrJsonObj.put("expire_seconds", 3600); //2592000
qrJsonObj.put("action_name", "QR_SCENE");
String qrJsonStr = HttpClientUtil.httpsPost(qrCodeCreateUrl, qrJsonObj.toJSONString());
if (qrJsonStr.contains("errorcode")) {
System.out.println(qrJsonStr);
return "";
}
String ticket = null;
try {
ticket = JSON.parseObject(qrJsonStr).getString("ticket");
} catch (Exception e) {
System.out.println(qrJsonStr);
return "";
}
if (StringUtils.isNotEmpty(ticket)) {
return QRCODE_GET_URL.replace("TICKET", ticket);
}
return "";
}