1. access_token用途与失效时间
access_token是公众号的全局唯一接口调用凭据,
公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。
access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时。
需定时刷新,重复获取将导致上次获取的access_token失效。
2. 接口调用请求说明
https请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
关于参数、返回值及详细信息,可在微信公众平台查看,这里提供传送门
微信公众平台-获取access_token
3. Java 代码实现
import com.google.gson.JsonObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Created by sean on 19/7/10.
*/
public class WeChatUtils {
private static final Logger logger = LoggerFactory.getLogger(WeChatUtils.class);
/*access_token 链接*/
private static final String ACCESS_TOKEN_REQUEST_URL = "https://api.weixin.qq.com/cgi-bin/token";
/*app_id*/
private static final String WX_LITE_APP_ID = "APP_ID";
/*app_secret*/
private static final String WX_LITE_APP_SECRET = "APP_SECRET";
private static Map<String,TokenExpire> map = new HashMap<>();
static class TokenExpire{
String key;
Date date;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
/**
* 获取accessToken
* @return accessToken
*/
public static String getAccessToken(){
TokenExpire expire = map.get("ticket");
if(null != expire){
if(expire.getDate().after(new Date())){
return expire.getKey();
}
}
String result = HttpUtils.get(ACCESS_TOKEN_REQUEST_URL +"?grant_type=client_credential&appid=" + WX_LITE_APP_ID + "&secret=" + WX_LITE_APP_SECRET ,null);
if(result.contains("access_token")){
JsonObject jsonObject = new JsonParser().parse(result ).getAsJsonObject();;
String accessToken = jsonObject.get("access_token").getAsString();
TokenExpire tokenExpire = new TokenExpire();
Date date = new Date();
date.setHours(new Date().getHours()+2);
tokenExpire.setDate(date);
tokenExpire.setKey(accessToken);
map.put("ticket",tokenExpire);
return accessToken;
}else{
logger.error(result);
}
return null;
}
}
4. 代码分析
代码中关于HTTP请求,已封装为HttpUtils工具类,读者可任意查找工具类替换即可。
处理 access_token 2小时失效问题,笔者在网上找到三种解决方案
1.存入数据库。当前时间+ expire_in 作为expireTime 和access_token一起存入数据库,
每次请求获取token时差数据库,比较expireTime和系统当前时间,如果过期获取新的
access_token,并更新数据库,没有过期则直接拿来用
2.存入配置文件。读取配置文件,过期则修改文件access_token
3.放入redis。设置redis过期时间为 2小时(建议设小于2小时),同时为了避免redis挂掉获取
不到access_token,可捕获redis宕机异常,在异常中执行获取access_token业务
笔者这里,是创建静态实体类,放入将access_token和过期时间放入map。