企业微信的access_token使用redis减少访问次数提升性能

企业微信的access_token使用redis减少访问次数提升性能

前言

此处引用为企业微信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.有疑问可以评论区交流。

原创!禁止转载!