|
|
|
@@ -46,11 +46,9 @@ import java.util.concurrent.atomic.AtomicBoolean; |
|
|
|
public class WxCpServiceImpl implements WxCpService { |
|
|
|
|
|
|
|
/** |
|
|
|
* 全局的是否正在刷新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(); |
|
|
|
|
|
|
|
protected WxCpConfigStorage wxCpConfigStorage; |
|
|
|
|
|
|
|
@@ -73,45 +71,37 @@ public class WxCpServiceImpl implements WxCpService { |
|
|
|
execute(new SimpleGetRequestExecutor(), url, null); |
|
|
|
} |
|
|
|
|
|
|
|
public void accessTokenRefresh() throws WxErrorException { |
|
|
|
if (!GLOBAL_ACCESS_TOKEN_REFRESH_FLAG.getAndSet(true)) { |
|
|
|
try { |
|
|
|
String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" |
|
|
|
+ "&corpid=" + wxCpConfigStorage.getCorpId() |
|
|
|
+ "&corpsecret=" + wxCpConfigStorage.getCorpSecret(); |
|
|
|
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); |
|
|
|
public String getAccessToken() throws WxErrorException { |
|
|
|
if (wxCpConfigStorage.isAccessTokenExpired()) { |
|
|
|
synchronized (GLOBAL_ACCESS_TOKEN_REFRESH_LOCK) { |
|
|
|
if (wxCpConfigStorage.isAccessTokenExpired()) { |
|
|
|
String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" |
|
|
|
+ "&corpid=" + wxCpConfigStorage.getCorpId() |
|
|
|
+ "&corpsecret=" + wxCpConfigStorage.getCorpSecret(); |
|
|
|
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); |
|
|
|
wxCpConfigStorage.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); |
|
|
|
} catch (ClientProtocolException e) { |
|
|
|
throw new RuntimeException(e); |
|
|
|
} catch (IOException e) { |
|
|
|
throw new RuntimeException(e); |
|
|
|
} |
|
|
|
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); |
|
|
|
wxCpConfigStorage.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 wxCpConfigStorage.getAccessToken(); |
|
|
|
} |
|
|
|
|
|
|
|
public void messageSend(WxCpMessage message) throws WxErrorException { |
|
|
|
@@ -369,10 +359,7 @@ public class WxCpServiceImpl implements WxCpService { |
|
|
|
* @throws WxErrorException |
|
|
|
*/ |
|
|
|
public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { |
|
|
|
if (StringUtils.isBlank(wxCpConfigStorage.getAccessToken())) { |
|
|
|
accessTokenRefresh(); |
|
|
|
} |
|
|
|
String accessToken = wxCpConfigStorage.getAccessToken(); |
|
|
|
String accessToken = getAccessToken(); |
|
|
|
|
|
|
|
String uriWithAccessToken = uri; |
|
|
|
uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken; |
|
|
|
@@ -387,7 +374,8 @@ public class WxCpServiceImpl implements WxCpService { |
|
|
|
* 42001 access_token超时 |
|
|
|
*/ |
|
|
|
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) { |
|
|
|
accessTokenRefresh(); |
|
|
|
// 强制设置wxCpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token |
|
|
|
wxCpConfigStorage.expireAccessToken(); |
|
|
|
return execute(executor, uri, data); |
|
|
|
} |
|
|
|
/** |
|
|
|
|