問題描述
問題導致的源頭:{"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 "";
}