为什么要缓存token?
这里的token指的是微信JSAPI中基础支持的ACCESS_TOKEN,并非网页授权ACCESS_TOKEN。网页授权Token每天的调用次数没有限制,不需要缓存。
接口 | 每日限额 |
---|---|
获取access_token | 2000 |
自定义菜单创建 | 1000 |
自定义菜单查询 | 10000 |
获取用户基本信息 | 5000000 |
获取网页授权access_token | 无 |
刷新网页授权access_token | 无 |
网页授权获取用户信息 | 无 |
从上面的表格我们可以看到,微信基础支持的token每天调用频次为2000次。而token的有效时间为7200s,当实现了token的全局缓存后,理论每天只需要调用12次。相反,2000次即使仅供微信分享回调,在有一定用户基础的项目中完全满足不了。
缓存方案
- 项目启动时开启一个定时器,每7180s执行一次Http请求,从微信获取最新的access_token并将redis中旧的access_token替换掉。
- 代码中有需要使用access_token时,直接从缓存中读取。
Spring Boot使用定时器
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.SQLException;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.bjb.dao.impl.RedisTokenHelper;
import net.sf.json.JSONObject;
/**
* 全局定时器
* @author qiqj
*
*/
@Component
public class Scheduler {
private final Logger logger = Logger.getRootLogger();
@Resource
private RedisTokenHelper redisTokenHelper;
/**
* 定时获取access_token
* @throws SQLException
*/
@Scheduled(fixedDelay=7180000)
public void getAccessToken() throws SQLException{
logger.info("==============开始获取access_token===============");
String access_token = null;
String grant_type = "client_credential";
String AppId= WxPropertiseUtil.getProperty("appid");
String secret= WxPropertiseUtil.getProperty("secret");
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type="+grant_type+"&appid="+AppId+"&secret="+secret;
try {
URL urlGet = new URL(url);
HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
http.setRequestMethod("GET"); // 必须是get方式请求
http.setRequestProperty("Content-Type"