本文針對《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;
}
}