| @@ -23,7 +23,6 @@ import me.chanjar.weixin.cp.bean.WxCpUser; | |||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import org.apache.http.HttpHost; | import org.apache.http.HttpHost; | ||||
| import org.apache.http.client.ClientProtocolException; | |||||
| import org.apache.http.client.config.RequestConfig; | import org.apache.http.client.config.RequestConfig; | ||||
| import org.apache.http.client.methods.CloseableHttpResponse; | import org.apache.http.client.methods.CloseableHttpResponse; | ||||
| import org.apache.http.client.methods.HttpGet; | import org.apache.http.client.methods.HttpGet; | ||||
| @@ -69,7 +68,7 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) { | public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) { | ||||
| try { | try { | ||||
| return SHA1.gen(this.configStorage.getToken(), timestamp, nonce, data) | return SHA1.gen(this.configStorage.getToken(), timestamp, nonce, data) | ||||
| .equals(msgSignature); | |||||
| .equals(msgSignature); | |||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -95,18 +94,18 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| synchronized (this.globalAccessTokenRefreshLock) { | synchronized (this.globalAccessTokenRefreshLock) { | ||||
| if (this.configStorage.isAccessTokenExpired()) { | if (this.configStorage.isAccessTokenExpired()) { | ||||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" | String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" | ||||
| + "&corpid=" + this.configStorage.getCorpId() | |||||
| + "&corpsecret=" + this.configStorage.getCorpSecret(); | |||||
| + "&corpid=" + this.configStorage.getCorpId() | |||||
| + "&corpsecret=" + this.configStorage.getCorpSecret(); | |||||
| try { | try { | ||||
| HttpGet httpGet = new HttpGet(url); | HttpGet httpGet = new HttpGet(url); | ||||
| if (this.httpProxy != null) { | if (this.httpProxy != null) { | ||||
| RequestConfig config = RequestConfig.custom() | RequestConfig config = RequestConfig.custom() | ||||
| .setProxy(this.httpProxy).build(); | |||||
| .setProxy(this.httpProxy).build(); | |||||
| httpGet.setConfig(config); | httpGet.setConfig(config); | ||||
| } | } | ||||
| String resultContent = null; | String resultContent = null; | ||||
| try (CloseableHttpClient httpclient = getHttpclient(); | try (CloseableHttpClient httpclient = getHttpclient(); | ||||
| CloseableHttpResponse response = httpclient.execute(httpGet)) { | |||||
| CloseableHttpResponse response = httpclient.execute(httpGet)) { | |||||
| resultContent = new BasicResponseHandler().handleResponse(response); | resultContent = new BasicResponseHandler().handleResponse(response); | ||||
| } finally { | } finally { | ||||
| httpGet.releaseConnection(); | httpGet.releaseConnection(); | ||||
| @@ -117,9 +116,7 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| } | } | ||||
| WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); | WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); | ||||
| this.configStorage.updateAccessToken( | this.configStorage.updateAccessToken( | ||||
| accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||||
| } catch (ClientProtocolException e) { | |||||
| throw new RuntimeException(e); | |||||
| accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||||
| } catch (IOException e) { | } catch (IOException e) { | ||||
| throw new RuntimeException(e); | throw new RuntimeException(e); | ||||
| } | } | ||||
| @@ -149,7 +146,7 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); | String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); | ||||
| int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); | int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); | ||||
| this.configStorage.updateJsapiTicket(jsapiTicket, | this.configStorage.updateJsapiTicket(jsapiTicket, | ||||
| expiresInSeconds); | |||||
| expiresInSeconds); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -162,10 +159,10 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| String noncestr = RandomUtils.getRandomStr(); | String noncestr = RandomUtils.getRandomStr(); | ||||
| String jsapiTicket = getJsapiTicket(false); | String jsapiTicket = getJsapiTicket(false); | ||||
| String signature = SHA1.genWithAmple( | String signature = SHA1.genWithAmple( | ||||
| "jsapi_ticket=" + jsapiTicket, | |||||
| "noncestr=" + noncestr, | |||||
| "timestamp=" + timestamp, | |||||
| "url=" + url | |||||
| "jsapi_ticket=" + jsapiTicket, | |||||
| "noncestr=" + noncestr, | |||||
| "timestamp=" + timestamp, | |||||
| "url=" + url | |||||
| ); | ); | ||||
| WxJsapiSignature jsapiSignature = new WxJsapiSignature(); | WxJsapiSignature jsapiSignature = new WxJsapiSignature(); | ||||
| jsapiSignature.setTimestamp(timestamp); | jsapiSignature.setTimestamp(timestamp); | ||||
| @@ -193,7 +190,7 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| @Override | @Override | ||||
| public void menuCreate(Integer agentId, WxMenu menu) throws WxErrorException { | public void menuCreate(Integer agentId, WxMenu menu) throws WxErrorException { | ||||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?agentid=" | String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?agentid=" | ||||
| + this.configStorage.getAgentId(); | |||||
| + this.configStorage.getAgentId(); | |||||
| post(url, menu.toJson()); | post(url, menu.toJson()); | ||||
| } | } | ||||
| @@ -230,7 +227,7 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| @Override | @Override | ||||
| public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) | public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) | ||||
| throws WxErrorException, IOException { | |||||
| throws WxErrorException, IOException { | |||||
| return mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); | return mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); | ||||
| } | } | ||||
| @@ -244,9 +241,9 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| public File mediaDownload(String media_id) throws WxErrorException { | public File mediaDownload(String media_id) throws WxErrorException { | ||||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/media/get"; | String url = "https://qyapi.weixin.qq.com/cgi-bin/media/get"; | ||||
| return execute( | return execute( | ||||
| new MediaDownloadRequestExecutor( | |||||
| this.configStorage.getTmpDirFile()), | |||||
| url, "media_id=" + media_id); | |||||
| new MediaDownloadRequestExecutor( | |||||
| this.configStorage.getTmpDirFile()), | |||||
| url, "media_id=" + media_id); | |||||
| } | } | ||||
| @@ -254,9 +251,9 @@ this.configStorage.getTmpDirFile()), | |||||
| public Integer departCreate(WxCpDepart depart) throws WxErrorException { | public Integer departCreate(WxCpDepart depart) throws WxErrorException { | ||||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/department/create"; | String url = "https://qyapi.weixin.qq.com/cgi-bin/department/create"; | ||||
| String responseContent = execute( | String responseContent = execute( | ||||
| new SimplePostRequestExecutor(), | |||||
| url, | |||||
| depart.toJson()); | |||||
| new SimplePostRequestExecutor(), | |||||
| url, | |||||
| depart.toJson()); | |||||
| JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | ||||
| return GsonHelper.getAsInteger(tmpJsonElement.getAsJsonObject().get("id")); | return GsonHelper.getAsInteger(tmpJsonElement.getAsJsonObject().get("id")); | ||||
| } | } | ||||
| @@ -283,11 +280,11 @@ this.configStorage.getTmpDirFile()), | |||||
| */ | */ | ||||
| JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | ||||
| return WxCpGsonBuilder.INSTANCE.create() | return WxCpGsonBuilder.INSTANCE.create() | ||||
| .fromJson( | |||||
| tmpJsonElement.getAsJsonObject().get("department"), | |||||
| new TypeToken<List<WxCpDepart>>() { | |||||
| }.getType() | |||||
| ); | |||||
| .fromJson( | |||||
| tmpJsonElement.getAsJsonObject().get("department"), | |||||
| new TypeToken<List<WxCpDepart>>() { | |||||
| }.getType() | |||||
| ); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -313,8 +310,8 @@ this.configStorage.getTmpDirFile()), | |||||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/user/batchdelete"; | String url = "https://qyapi.weixin.qq.com/cgi-bin/user/batchdelete"; | ||||
| JsonObject jsonObject = new JsonObject(); | JsonObject jsonObject = new JsonObject(); | ||||
| JsonArray jsonArray = new JsonArray(); | JsonArray jsonArray = new JsonArray(); | ||||
| for (int i = 0; i < userids.length; i++) { | |||||
| jsonArray.add(new JsonPrimitive(userids[i])); | |||||
| for (String userid : userids) { | |||||
| jsonArray.add(new JsonPrimitive(userid)); | |||||
| } | } | ||||
| jsonObject.add("useridlist", jsonArray); | jsonObject.add("useridlist", jsonArray); | ||||
| post(url, jsonObject.toString()); | post(url, jsonObject.toString()); | ||||
| @@ -343,11 +340,11 @@ this.configStorage.getTmpDirFile()), | |||||
| String responseContent = get(url, params); | String responseContent = get(url, params); | ||||
| JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | ||||
| return WxCpGsonBuilder.INSTANCE.create() | return WxCpGsonBuilder.INSTANCE.create() | ||||
| .fromJson( | |||||
| tmpJsonElement.getAsJsonObject().get("userlist"), | |||||
| new TypeToken<List<WxCpUser>>() { | |||||
| }.getType() | |||||
| ); | |||||
| .fromJson( | |||||
| tmpJsonElement.getAsJsonObject().get("userlist"), | |||||
| new TypeToken<List<WxCpUser>>() { | |||||
| }.getType() | |||||
| ); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -366,11 +363,11 @@ this.configStorage.getTmpDirFile()), | |||||
| String responseContent = get(url, params); | String responseContent = get(url, params); | ||||
| JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | ||||
| return WxCpGsonBuilder.INSTANCE.create() | return WxCpGsonBuilder.INSTANCE.create() | ||||
| .fromJson( | |||||
| tmpJsonElement.getAsJsonObject().get("userlist"), | |||||
| new TypeToken<List<WxCpUser>>() { | |||||
| }.getType() | |||||
| ); | |||||
| .fromJson( | |||||
| tmpJsonElement.getAsJsonObject().get("userlist"), | |||||
| new TypeToken<List<WxCpUser>>() { | |||||
| }.getType() | |||||
| ); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -404,11 +401,11 @@ this.configStorage.getTmpDirFile()), | |||||
| String responseContent = get(url, null); | String responseContent = get(url, null); | ||||
| JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | ||||
| return WxCpGsonBuilder.INSTANCE.create() | return WxCpGsonBuilder.INSTANCE.create() | ||||
| .fromJson( | |||||
| tmpJsonElement.getAsJsonObject().get("taglist"), | |||||
| new TypeToken<List<WxCpTag>>() { | |||||
| }.getType() | |||||
| ); | |||||
| .fromJson( | |||||
| tmpJsonElement.getAsJsonObject().get("taglist"), | |||||
| new TypeToken<List<WxCpTag>>() { | |||||
| }.getType() | |||||
| ); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -417,11 +414,11 @@ this.configStorage.getTmpDirFile()), | |||||
| String responseContent = get(url, null); | String responseContent = get(url, null); | ||||
| JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | ||||
| return WxCpGsonBuilder.INSTANCE.create() | return WxCpGsonBuilder.INSTANCE.create() | ||||
| .fromJson( | |||||
| tmpJsonElement.getAsJsonObject().get("userlist"), | |||||
| new TypeToken<List<WxCpUser>>() { | |||||
| }.getType() | |||||
| ); | |||||
| .fromJson( | |||||
| tmpJsonElement.getAsJsonObject().get("userlist"), | |||||
| new TypeToken<List<WxCpUser>>() { | |||||
| }.getType() | |||||
| ); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -460,14 +457,14 @@ this.configStorage.getTmpDirFile()), | |||||
| } | } | ||||
| @Override | @Override | ||||
| public String oauth2buildAuthorizationUrl(String state) { | |||||
| return this.oauth2buildAuthorizationUrl( | |||||
| this.configStorage.getOauth2redirectUri(), | |||||
| state | |||||
| ); | |||||
| } | |||||
| public String oauth2buildAuthorizationUrl(String state) { | |||||
| return this.oauth2buildAuthorizationUrl( | |||||
| this.configStorage.getOauth2redirectUri(), | |||||
| state | |||||
| ); | |||||
| } | |||||
| @Override | |||||
| @Override | |||||
| public String oauth2buildAuthorizationUrl(String redirectUri, String state) { | public String oauth2buildAuthorizationUrl(String redirectUri, String state) { | ||||
| String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"; | String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"; | ||||
| url += "appid=" + this.configStorage.getCorpId(); | url += "appid=" + this.configStorage.getCorpId(); | ||||
| @@ -489,8 +486,8 @@ this.configStorage.getOauth2redirectUri(), | |||||
| @Override | @Override | ||||
| public String[] oauth2getUserInfo(Integer agentId, String code) throws WxErrorException { | public String[] oauth2getUserInfo(Integer agentId, String code) throws WxErrorException { | ||||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?" | String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?" | ||||
| + "code=" + code | |||||
| + "&agentid=" + agentId; | |||||
| + "code=" + code | |||||
| + "&agentid=" + agentId; | |||||
| String responseText = get(url, null); | String responseText = get(url, null); | ||||
| JsonElement je = new JsonParser().parse(responseText); | JsonElement je = new JsonParser().parse(responseText); | ||||
| JsonObject jo = je.getAsJsonObject(); | JsonObject jo = je.getAsJsonObject(); | ||||
| @@ -544,14 +541,14 @@ this.configStorage.getOauth2redirectUri(), | |||||
| return executeInternal(executor, uri, data); | return executeInternal(executor, uri, data); | ||||
| } catch (WxErrorException e) { | } catch (WxErrorException e) { | ||||
| WxError error = e.getError(); | WxError error = e.getError(); | ||||
| /** | |||||
| /* | |||||
| * -1 系统繁忙, 1000ms后重试 | * -1 系统繁忙, 1000ms后重试 | ||||
| */ | */ | ||||
| if (error.getErrorCode() == -1) { | if (error.getErrorCode() == -1) { | ||||
| int sleepMillis = this.retrySleepMillis * (1 << retryTimes); | int sleepMillis = this.retrySleepMillis * (1 << retryTimes); | ||||
| try { | try { | ||||
| this.log.debug("微信系统繁忙,{}ms 后重试(第{}次)", sleepMillis, | this.log.debug("微信系统繁忙,{}ms 后重试(第{}次)", sleepMillis, | ||||
| retryTimes + 1); | |||||
| retryTimes + 1); | |||||
| Thread.sleep(sleepMillis); | Thread.sleep(sleepMillis); | ||||
| } catch (InterruptedException e1) { | } catch (InterruptedException e1) { | ||||
| throw new RuntimeException(e1); | throw new RuntimeException(e1); | ||||
| @@ -566,7 +563,7 @@ this.configStorage.getOauth2redirectUri(), | |||||
| } | } | ||||
| protected synchronized <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | protected synchronized <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | ||||
| if (uri.indexOf("access_token=") != -1) { | |||||
| if (uri.contains("access_token=")) { | |||||
| throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); | throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); | ||||
| } | } | ||||
| String accessToken = getAccessToken(false); | String accessToken = getAccessToken(false); | ||||
| @@ -576,7 +573,7 @@ this.configStorage.getOauth2redirectUri(), | |||||
| try { | try { | ||||
| return executor.execute(getHttpclient(), this.httpProxy, | return executor.execute(getHttpclient(), this.httpProxy, | ||||
| uriWithAccessToken, data); | |||||
| uriWithAccessToken, data); | |||||
| } catch (WxErrorException e) { | } catch (WxErrorException e) { | ||||
| WxError error = e.getError(); | WxError error = e.getError(); | ||||
| /* | /* | ||||
| @@ -593,8 +590,6 @@ this.configStorage.getOauth2redirectUri(), | |||||
| throw new WxErrorException(error); | throw new WxErrorException(error); | ||||
| } | } | ||||
| return null; | return null; | ||||
| } catch (ClientProtocolException e) { | |||||
| throw new RuntimeException(e); | |||||
| } catch (IOException e) { | } catch (IOException e) { | ||||
| throw new RuntimeException(e); | throw new RuntimeException(e); | ||||
| } | } | ||||
| @@ -608,15 +603,15 @@ this.configStorage.getOauth2redirectUri(), | |||||
| public void setWxCpConfigStorage(WxCpConfigStorage wxConfigProvider) { | public void setWxCpConfigStorage(WxCpConfigStorage wxConfigProvider) { | ||||
| this.configStorage = wxConfigProvider; | this.configStorage = wxConfigProvider; | ||||
| ApacheHttpClientBuilder apacheHttpClientBuilder = this.configStorage | ApacheHttpClientBuilder apacheHttpClientBuilder = this.configStorage | ||||
| .getApacheHttpClientBuilder(); | |||||
| .getApacheHttpClientBuilder(); | |||||
| if (null == apacheHttpClientBuilder) { | if (null == apacheHttpClientBuilder) { | ||||
| apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get(); | apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get(); | ||||
| } | } | ||||
| apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost()) | apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost()) | ||||
| .httpProxyPort(this.configStorage.getHttpProxyPort()) | |||||
| .httpProxyUsername(this.configStorage.getHttpProxyUsername()) | |||||
| .httpProxyPassword(this.configStorage.getHttpProxyPassword()); | |||||
| .httpProxyPort(this.configStorage.getHttpProxyPort()) | |||||
| .httpProxyUsername(this.configStorage.getHttpProxyUsername()) | |||||
| .httpProxyPassword(this.configStorage.getHttpProxyPassword()); | |||||
| if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) { | if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) { | ||||
| this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort()); | this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort()); | ||||