本文针对《fastweixin框架》 代码不适用于实际情况进行修改。
修改原因:
获得AccessToken接口频率有限制,建议进行缓存,注意有效期,本文写作时候是access_token有效期是7200秒,也就是两小时。
原框架没有固化保存方法,一般可以考虑保存到数据库,但读取时候发现QYAPIConfig没有赋值AccessToken的方法
修改方法:
修改QYAPIConfig类,自己继承实现新类。
package com.fastwixinextend; import com.github.sd4324530.fastweixin.api.config.ChangeType; import com.github.sd4324530.fastweixin.api.config.ConfigChangeNotice; import com.github.sd4324530.fastweixin.api.response.GetJsApiTicketResponse; import com.github.sd4324530.fastweixin.api.response.GetTokenResponse; import com.github.sd4324530.fastweixin.company.api.config.QYAPIConfig; import com.github.sd4324530.fastweixin.exception.WeixinException; import com.github.sd4324530.fastweixin.handle.ApiConfigChangeHandle; import com.github.sd4324530.fastweixin.util.JSONUtil; import com.github.sd4324530.fastweixin.util.NetWorkCenter; import com.github.sd4324530.fastweixin.util.StrUtil; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.http.HttpStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class QYAPIConfigExt extends QYAPIConfig { private static final Logger LOG = LoggerFactory.getLogger(QYAPIConfig.class); private static final long serialVersionUID = 1L; private Integer CACHE_TIME = 7100 * 1000; private final AtomicBoolean tokenRefreshing = new AtomicBoolean(false); private final AtomicBoolean jsRefreshing = new AtomicBoolean(false); private final String corpid; private final String corpsecret; protected String accessToken; private String jsApiTicket; private boolean enableJsApi; private long jsTokenStartTime; protected long weixinTokenStartTime; /** * 构造方法二,实现同时获取AccessToken,启用jsApi * * @param corpid corpid * @param corpsecret corpsecret * @param enableJsApi enableJsApi */ public QYAPIConfigExt(String corpid, String corpsecret, boolean enableJsApi) { super(corpid, corpsecret, enableJsApi); this.corpid = corpid; this.corpsecret = corpsecret; this.enableJsApi = enableJsApi; } /** * 构造方法一,实现同时获取AccessToken。不启用jsApi * * @param corpID corpID * @param corpSecret corpSecret */ public QYAPIConfigExt(String corpID, String corpSecret) { this(corpID, corpSecret, false); } /** * 构造方法一,实现同时获取AccessToken。不启用jsApi * * @param corpID corpID * @param corpSecret corpSecret * @param accessToken * @param weixinTokenStartTime */ public QYAPIConfigExt(String corpID, String corpSecret, String accessToken, long weixinTokenStartTime) { this(corpID, corpSecret, false); this.accessToken = accessToken; this.setWeixinTokenStartTime(weixinTokenStartTime); } /** * 构造方法一,实现同时获取AccessToken。不启用jsApi * * @param corpID corpID * @param corpSecret corpSecret * @param accessToken * @param weixinTokenStartTime */ public QYAPIConfigExt(String corpID, String corpSecret, String accessToken, long weixinTokenStartTime, int CACHE_TIME) { this(corpID, corpSecret, false); this.accessToken = accessToken; this.setWeixinTokenStartTime(weixinTokenStartTime); this.setCACHE_TIME(CACHE_TIME); } public String getCorpid() { return corpid; } public String getCorpsecret() { return corpsecret; } public String getAccessToken() { long now = System.currentTimeMillis(); long time = now - this.weixinTokenStartTime; try { if (time > CACHE_TIME && tokenRefreshing.compareAndSet(false, true)) { LOG.debug("准备刷新tokean........."); initToken(now); } } catch (Exception e) { LOG.error("刷新token异常", e); tokenRefreshing.set(false); } return accessToken; } public String getJsApiTicket() { if (enableJsApi) { long now = System.currentTimeMillis(); long time = now - this.jsTokenStartTime; try { if (now - this.jsTokenStartTime > CACHE_TIME && jsRefreshing.compareAndSet(false, true)) { LOG.debug("准备刷新JSTokean.........."); getAccessToken(); initJSToken(now); } } catch (Exception e) { LOG.error("刷新jsToken异常", e); jsRefreshing.set(false); } } else { jsApiTicket = null; } return jsApiTicket; } public boolean isEnableJsApi() { return enableJsApi; } public void setEnableJsApi(boolean enableJsApi) { this.enableJsApi = enableJsApi; if (!enableJsApi) { this.jsApiTicket = null; } } public void addHandle(final ApiConfigChangeHandle handle) { super.addObserver(handle); } public void removeHandle(final ApiConfigChangeHandle handle) { super.deleteObserver(handle); } public void removeAllHandle() { super.deleteObservers(); } private void initToken(final long refreshTime) { LOG.debug("开始初始化access_token.........."); // 记住原本的事件,用于出错回滚 final long oldTime = this.getWeixinTokenStartTime(); this.setWeixinTokenStartTime(refreshTime); String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpid + "&corpsecret=" + corpsecret; NetWorkCenter.get(url, null, new NetWorkCenter.ResponseCallback() { @Override public void onResponse(int resultCode, String resultJson) { if (HttpStatus.SC_OK == resultCode) { GetTokenResponse response = JSONUtil.toBean(resultJson, GetTokenResponse.class); LOG.debug("获取access_token:{}", response.getAccessToken()); if (null == response.getAccessToken()) { // 刷新时间回滚 setWeixinTokenStartTime(oldTime); throw new WeixinException("微信企业号token获取出错,错误信息:" + response.getErrcode() + "," + response.getErrmsg()); } accessToken = response.getAccessToken(); // 设置通知点 setChanged(); notifyObservers(new ConfigChangeNotice(corpid, ChangeType.ACCESS_TOKEN, accessToken)); } } }); tokenRefreshing.set(false); } private void initJSToken(final long refreshTime) { LOG.debug("初始化 jsapi_ticket........."); // 记住原本的事件,用于出错回滚 final long oldTime = this.getJsTokenStartTime(); this.setJsTokenStartTime(refreshTime); String url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=" + accessToken; NetWorkCenter.get(url, null, new NetWorkCenter.ResponseCallback() { @Override public void onResponse(int resultCode, String resultJson) { if (HttpStatus.SC_OK == resultCode) { GetJsApiTicketResponse response = JSONUtil.toBean(resultJson, GetJsApiTicketResponse.class); LOG.debug("获取jsapi_ticket:{}", response.getTicket()); if (StrUtil.isBlank(response.getTicket())) { //刷新时间回滚 setJsTokenStartTime(oldTime); throw new WeixinException("微信企业号jsToken获取出错,错误信息:" + response.getErrcode() + "," + response.getErrmsg()); } jsApiTicket = response.getTicket(); //设置通知点 setChanged(); notifyObservers(new ConfigChangeNotice(corpid, ChangeType.JS_TOKEN, jsApiTicket)); } } }); jsRefreshing.set(false); } public Integer getCACHE_TIME() { return CACHE_TIME; } private void setCACHE_TIME(Integer CACHE_TIME) { this.CACHE_TIME = CACHE_TIME; } public long getJsTokenStartTime() { return jsTokenStartTime; } private void setJsTokenStartTime(long jsTokenStartTime) { this.jsTokenStartTime = jsTokenStartTime; } public long getWeixinTokenStartTime() { return weixinTokenStartTime; } private void setWeixinTokenStartTime(long weixinTokenStartTime) { this.weixinTokenStartTime = weixinTokenStartTime; } }