diff --git a/weixin-java-cp/src/test/resources/test-config.sample.xml b/weixin-java-cp/src/test/resources/test-config.sample.xml
index 02c98f3f7..aa99a962b 100644
--- a/weixin-java-cp/src/test/resources/test-config.sample.xml
+++ b/weixin-java-cp/src/test/resources/test-config.sample.xml
@@ -5,7 +5,7 @@
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
index 636e8f622..0bb1c550a 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
@@ -44,12 +44,15 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class WxMpServiceImpl implements WxMpService {
/**
- * 全局的是否正在刷新Access Token的flag
- * true: 正在刷新
- * false: 没有刷新
+ * 全局的是否正在刷新access token的锁
*/
- protected static final AtomicBoolean GLOBAL_ACCESS_TOKEN_REFRESH_FLAG = new AtomicBoolean(false);
-
+ protected static final Object GLOBAL_ACCESS_TOKEN_REFRESH_LOCK = new Object();
+
+ /**
+ * 全局的是否正在刷新jsapi_ticket的锁
+ */
+ protected static final Object GLOBAL_JSAPI_TICKET_REFRESH_LOCK = new Object();
+
protected WxMpConfigStorage wxMpConfigStorage;
protected final ThreadLocal retryTimes = new ThreadLocal();
@@ -66,52 +69,45 @@ public class WxMpServiceImpl implements WxMpService {
}
}
- public void accessTokenRefresh() throws WxErrorException {
- if (!GLOBAL_ACCESS_TOKEN_REFRESH_FLAG.getAndSet(true)) {
- try {
- String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential"
- + "&appid=" + wxMpConfigStorage.getAppId()
- + "&secret=" + wxMpConfigStorage.getSecret()
- ;
- try {
- HttpGet httpGet = new HttpGet(url);
- if (httpProxy != null) {
- RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
- httpGet.setConfig(config);
+ public String getAccessToken() throws WxErrorException {
+ if (wxMpConfigStorage.isAccessTokenExpired()) {
+ synchronized (GLOBAL_ACCESS_TOKEN_REFRESH_LOCK) {
+ if (wxMpConfigStorage.isAccessTokenExpired()) {
+ String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential"
+ + "&appid=" + wxMpConfigStorage.getAppId()
+ + "&secret=" + wxMpConfigStorage.getSecret()
+ ;
+ try {
+ HttpGet httpGet = new HttpGet(url);
+ if (httpProxy != null) {
+ RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
+ httpGet.setConfig(config);
+ }
+ CloseableHttpClient httpclient = getHttpclient();
+ CloseableHttpResponse response = httpclient.execute(httpGet);
+ String resultContent = new BasicResponseHandler().handleResponse(response);
+ WxError error = WxError.fromJson(resultContent);
+ if (error.getErrorCode() != 0) {
+ throw new WxErrorException(error);
+ }
+ WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
+ wxMpConfigStorage.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
+ } catch (ClientProtocolException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
}
- CloseableHttpClient httpclient = getHttpclient();
- CloseableHttpResponse response = httpclient.execute(httpGet);
- String resultContent = new BasicResponseHandler().handleResponse(response);
- WxError error = WxError.fromJson(resultContent);
- if (error.getErrorCode() != 0) {
- throw new WxErrorException(error);
- }
- WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
- wxMpConfigStorage.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
- } catch (ClientProtocolException e) {
- throw new RuntimeException(e);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- } finally {
- GLOBAL_ACCESS_TOKEN_REFRESH_FLAG.set(false);
- }
- } else {
- // 每隔100ms检查一下是否刷新完毕了
- while (GLOBAL_ACCESS_TOKEN_REFRESH_FLAG.get()) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
}
}
- // 刷新完毕了,就没他什么事儿了
}
+ return wxMpConfigStorage.getAccessToken();
}
+
public String getJsapiTicket() throws WxErrorException {
- if (wxMpConfigStorage.isJsapiTokenExpired()) {
- synchronized (wxMpConfigStorage) {
- if (wxMpConfigStorage.isJsapiTokenExpired()) {
+ if (wxMpConfigStorage.isJsapiTicketExpired()) {
+ synchronized (GLOBAL_JSAPI_TICKET_REFRESH_LOCK) {
+ if (wxMpConfigStorage.isJsapiTicketExpired()) {
String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi";
String responseContent = execute(new SimpleGetRequestExecutor(), url, null);
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
@@ -440,10 +436,7 @@ public class WxMpServiceImpl implements WxMpService {
* @throws WxErrorException
*/
public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException {
- if (StringUtils.isBlank(wxMpConfigStorage.getAccessToken())) {
- accessTokenRefresh();
- }
- String accessToken = wxMpConfigStorage.getAccessToken();
+ String accessToken = getAccessToken();
String uriWithAccessToken = uri;
uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken;
@@ -458,7 +451,8 @@ public class WxMpServiceImpl implements WxMpService {
* 42001 access_token超时
*/
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) {
- accessTokenRefresh();
+ // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token
+ wxMpConfigStorage.expireAccessToken();
return execute(executor, uri, data);
}
/**
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java
index c2a285469..d2a6ef8ec 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java
@@ -65,7 +65,7 @@ public class WxMpOAuth2AccessToken {
public String toString() {
return "WxMpOAuth2AccessToken{" +
"accessToken='" + accessToken + '\'' +
- ", expiresIn=" + expiresIn +
+ ", expiresTime=" + expiresIn +
", refreshToken='" + refreshToken + '\'' +
", openId='" + openId + '\'' +
", scope='" + scope + '\'' +
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/ApiTestModule.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/ApiTestModule.java
index ad006acd4..e6df8e343 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/ApiTestModule.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/ApiTestModule.java
@@ -42,7 +42,7 @@ public class ApiTestModule implements Module {
@Override
public String toString() {
return "SimpleWxConfigProvider [appId=" + appId + ", secret=" + secret + ", accessToken=" + accessToken
- + ", expiresIn=" + expiresIn + ", token=" + token + ", openId=" + openId + "]";
+ + ", expiresTime=" + expiresTime + ", token=" + token + ", openId=" + openId + "]";
}
}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBaseAPITest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBaseAPITest.java
index ef9590e69..e773f117b 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBaseAPITest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBaseAPITest.java
@@ -22,7 +22,7 @@ public class WxMpBaseAPITest {
public void testRefreshAccessToken() throws WxErrorException {
WxMpConfigStorage configStorage = wxService.wxMpConfigStorage;
String before = configStorage.getAccessToken();
- wxService.accessTokenRefresh();
+ wxService.getAccessToken();
String after = configStorage.getAccessToken();
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java
index 22d87dd49..becfbeb4d 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java
@@ -16,7 +16,7 @@ class WxMpDemoInMemoryConfigStorage extends WxMpInMemoryConfigStorage {
@Override
public String toString() {
return "SimpleWxConfigProvider [appId=" + appId + ", secret=" + secret + ", accessToken=" + accessToken
- + ", expiresIn=" + expiresIn + ", token=" + token + ", aesKey=" + aesKey + "]";
+ + ", expiresTime=" + expiresTime + ", token=" + token + ", aesKey=" + aesKey + "]";
}
diff --git a/weixin-java-mp/src/test/resources/test-config.sample.xml b/weixin-java-mp/src/test/resources/test-config.sample.xml
index 19535f3c7..6ec4825a9 100644
--- a/weixin-java-mp/src/test/resources/test-config.sample.xml
+++ b/weixin-java-mp/src/test/resources/test-config.sample.xml
@@ -4,7 +4,7 @@
公众号Token
公众号EncodingAESKey
可以不填写
- 可以不填写
+ 可以不填写
某个加你公众号的用户的openId
网页授权获取用户信息回调地址