前言
此处引用为企业微信API的话:
开发者需要缓存access_token,用于后续接口的调用(注意:不能频繁调用gettoken接口,否则会受到频率拦截)。当access_token失效或过期时,需要重新获取。
1.access_token的有效期通过返回的expires_in来传达,正常情况下为7200秒(2小时),有效期内重复获取返回相同结果,过期后获取会返回新的access_token。
2.由于企业微信每个应用的access_token是彼此独立的,所以进行缓存时需要区分应用来进行存储。
3.access_token至少保留512字节的存储空间。
4.企业微信可能会出于运营需要,提前使access_token失效,开发者应实现access_token失效时重新获取的逻辑。
代码实现
/**
* 获取access_token
*
* @throws Exception Exception
* @return String access_token
*/
public String getAccessToken() throws Exception {
CacheInterface objCache = CacheManager.getServiceInstance("redis");
if (null == objCache) {
LOGGER.error("redis获取失败,请检查配置");
return null;
}
// 从redis拿access_token
String strAccessToken = (String) objCache.getAttribute(RedisKeyEnum.ELINK_ACCESS_TOKEN.getKey());
// 如果redis里没有,则重新调http获取,以及存放到redis里
if (StringUtils.isEmpty(strAccessToken)) {
// 通过http获取最新access_token,且存到redis
return getAccessTokenByHttp(objCache);
} else {
// 如果redis里有,则先校验access_token失效有效时间是否快到了
String[] strs = strAccessToken.split(",");
// 从redis里拿出来的失效日期
String strValidTime = strs[1];
// 调用字符串转日期的工具类,得到失效日期
Date objValidTime = TimeUtil.toDate(strValidTime, "yyyy-MM-dd HH:mm:ss");
// 当前时间+有效时间低于规定时间(秒)默认600秒
Date objNow = TimeUtil.addTime(new Date(), 600);
if (objNow.getTime() >= objValidTime.getTime()) {
// 通过http获取最新access_token,且存到redis
return getAccessTokenByHttp(objCache);
} else {
return strs[0]; // 直接返回access_token
}
}
}
/**
* 获取最新access_token,且存到redis
*
* @param cache CacheInterface
* @return String access_token
*/
private String getAccessTokenByHttp(final CacheInterface cache) throws Exception{
// 拼接获取access_token的url
String strUrl = accessTokenUrl + "?corpid=" + appId + "&corpsecret=" + corpSecret;
// 调用get方法获取
String strResult = httpUtil.doGet(strUrl);
if (!StringUtils.isEmpty(strResult)) {
// 把响应报文转成json对象
JSONObject objJsonObject = (JSONObject) JSONObject.parse(strResult);
if (null != objJsonObject) {
// 出错返回码,为0表示成功,非0表示调用失败
int iErrorCode = objJsonObject.getIntValue("errorCode");
if (iErrorCode == 0) {
// 计算出失效日期
int iExpiresIn = objJsonObject.getIntValue("expires_in");
String strValidTime = TimeUtil.addTimeStr(new Date(), iExpiresIn);
// 把access_token和时间拼接,以逗号隔开,存放到redis里
String strAccessToken = objJsonObject.getString("access_token");
String strAccessTokenAndTime = strAccessToken + "," + strValidTime;
// 设置到redis里,目前的存活时间为120分钟(7200秒)
cache.setAttribute(RedisKeyEnum.ELINK_ACCESS_TOKEN.getKey(), strAccessTokenAndTime, 7200);
return strAccessToken;
}
}
}
return null;
}
总结
1.实现也是比较简单,使用redis来提升性能,减少访问微信的频率。微信也有限制访问频率,使用缓存也能避免这个问题。
2.这里只是讲解access_token使用redis的处理方式,suite_access_token也是同理。
3.有疑问可以评论区交流。
原创!禁止转载!