| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -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); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      /** | 
		
		
	
	
		
			
				| 
				
					
				
				
				
				 | 
			
			 | 
			
  |