diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/ApacheHttpClientBuilder.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/ApacheHttpClientBuilder.java new file mode 100644 index 00000000..1bd6a98c --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/ApacheHttpClientBuilder.java @@ -0,0 +1,51 @@ +package me.chanjar.weixin.common.util.http; + +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.CloseableHttpClient; + +/** + * httpclient build interface + */ +public interface ApacheHttpClientBuilder { + + /** + * 构建httpclient实例 + * @return new instance of CloseableHttpClient + */ + CloseableHttpClient build(); + + /** + * 代理服务器地址 + * @param httpProxyHost + * @return + */ + ApacheHttpClientBuilder httpProxyHost(String httpProxyHost); + + /** + * 代理服务器端口 + * @param httpProxyPort + * @return + */ + ApacheHttpClientBuilder httpProxyPort(int httpProxyPort); + + /** + * 代理服务器用户名 + * @param httpProxyUsername + * @return + */ + ApacheHttpClientBuilder httpProxyUsername(String httpProxyUsername); + + /** + * 代理服务器密码 + * @param httpProxyPassword + * @return + */ + ApacheHttpClientBuilder httpProxyPassword(String httpProxyPassword); + + /** + * ssl连接socket工厂 + * @param sslConnectionSocketFactory + * @return + */ + ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory); +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/DefaultApacheHttpHttpClientBuilder.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/DefaultApacheHttpHttpClientBuilder.java new file mode 100644 index 00000000..aa20fa0b --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/DefaultApacheHttpHttpClientBuilder.java @@ -0,0 +1,199 @@ +package me.chanjar.weixin.common.util.http; + +import me.chanjar.weixin.common.util.StringUtils; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.HttpRequestRetryHandler; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.config.SocketConfig; +import org.apache.http.conn.HttpClientConnectionManager; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.protocol.HttpContext; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + * httpclient 连接管理器 + */ +@NotThreadSafe +public class DefaultApacheHttpHttpClientBuilder implements ApacheHttpClientBuilder { + private int connectionRequestTimeout = 3000; + private int connectionTimeout = 5000; + private int soTimeout = 5000; + private int idleConnTimeout = 60000; + private int checkWaitTime = 5000; + private int maxConnPerHost = 10; + private int maxTotalConn = 50; + private String userAgent; + private HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() { + @Override + public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { + return false; + } + }; + private SSLConnectionSocketFactory sslConnectionSocketFactory = SSLConnectionSocketFactory.getSocketFactory(); + private PlainConnectionSocketFactory plainConnectionSocketFactory = PlainConnectionSocketFactory.getSocketFactory(); + + private String httpProxyHost; + private int httpProxyPort; + private String httpProxyUsername; + private String httpProxyPassword; + + /** + * 连接管理器 + */ + private PoolingHttpClientConnectionManager connectionManager; + /** + * 闲置连接监控线程 + */ + private IdleConnectionMonitorThread idleConnectionMonitorThread; + + /** + * httpClientBuilder + */ + private HttpClientBuilder httpClientBuilder; + + private boolean prepared = false; + + private DefaultApacheHttpHttpClientBuilder() { + } + + public static DefaultApacheHttpHttpClientBuilder get() { + return new DefaultApacheHttpHttpClientBuilder(); + } + + public ApacheHttpClientBuilder httpProxyHost(String httpProxyHost) { + this.httpProxyHost = httpProxyHost; + return this; + } + + public ApacheHttpClientBuilder httpProxyPort(int httpProxyPort) { + this.httpProxyPort = httpProxyPort; + return this; + } + + public ApacheHttpClientBuilder httpProxyUsername(String httpProxyUsername) { + this.httpProxyUsername = httpProxyUsername; + return this; + } + + public ApacheHttpClientBuilder httpProxyPassword(String httpProxyPassword) { + this.httpProxyPassword = httpProxyPassword; + return this; + } + + public ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory){ + this.sslConnectionSocketFactory = sslConnectionSocketFactory; + return this; + } + + public IdleConnectionMonitorThread getIdleConnectionMonitorThread() { + return idleConnectionMonitorThread; + } + + private void prepare(){ + Registry registry = RegistryBuilder.create() + .register("http", plainConnectionSocketFactory) + .register("https", sslConnectionSocketFactory) + .build(); + connectionManager = new PoolingHttpClientConnectionManager(registry); + connectionManager.setMaxTotal(maxTotalConn); + connectionManager.setDefaultMaxPerRoute(maxConnPerHost); + connectionManager.setDefaultSocketConfig( + SocketConfig.copy(SocketConfig.DEFAULT) + .setSoTimeout(soTimeout) + .build() + ); + + idleConnectionMonitorThread = new IdleConnectionMonitorThread(connectionManager, idleConnTimeout, checkWaitTime); + idleConnectionMonitorThread.setDaemon(true); + idleConnectionMonitorThread.start(); + + httpClientBuilder = HttpClients.custom() + .setConnectionManager(connectionManager) + .setDefaultRequestConfig( + RequestConfig.custom() + .setSocketTimeout(soTimeout) + .setConnectTimeout(connectionTimeout) + .setConnectionRequestTimeout(connectionRequestTimeout) + .build() + ) + .setRetryHandler(httpRequestRetryHandler); + + if (StringUtils.isNotBlank(httpProxyHost) && StringUtils.isNotBlank(httpProxyUsername)) { + // 使用代理服务器 需要用户认证的代理服务器 + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials( + new AuthScope(httpProxyHost, httpProxyPort), + new UsernamePasswordCredentials(httpProxyUsername, httpProxyPassword)); + httpClientBuilder.setDefaultCredentialsProvider(credsProvider); + } + + if (StringUtils.isNotBlank(userAgent)) { + httpClientBuilder.setUserAgent(userAgent); + } + + } + + public CloseableHttpClient build() { + if(!prepared){ + prepare(); + prepared = true; + } + + return httpClientBuilder.build(); + } + + public static class IdleConnectionMonitorThread extends Thread { + private final HttpClientConnectionManager connMgr; + private final int idleConnTimeout; + private final int checkWaitTime; + private volatile boolean shutdown; + + public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr, int idleConnTimeout, int checkWaitTime) { + super("IdleConnectionMonitorThread"); + this.connMgr = connMgr; + this.idleConnTimeout = idleConnTimeout; + this.checkWaitTime = checkWaitTime; + } + + @Override + public void run() { + try { + while (!shutdown) { + synchronized (this) { + wait(checkWaitTime); + connMgr.closeExpiredConnections(); + connMgr.closeIdleConnections(idleConnTimeout, TimeUnit.MILLISECONDS); + } + } + } catch (InterruptedException ignore) { + } + } + + public void trigger() { + synchronized (this) { + notifyAll(); + } + } + + public void shutdown() { + shutdown = true; + synchronized (this) { + notifyAll(); + } + } + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/JoddGetRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/JoddGetRequestExecutor.java index 82e28f7f..10011304 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/JoddGetRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/JoddGetRequestExecutor.java @@ -33,7 +33,7 @@ public class JoddGetRequestExecutor implements RequestExecutor { if (httpProxy != null) { ProxyInfo proxyInfoObj = new ProxyInfo( ProxyInfo.ProxyType.HTTP, - httpProxy.getAddress().getHostAddress(), + httpProxy.getHostName(), httpProxy.getPort(), "", ""); provider.useProxy(proxyInfoObj); } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java index f9e3a25f..c0bd21ce 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java @@ -74,6 +74,8 @@ public class MediaDownloadRequestExecutor implements RequestExecutor throw new WxErrorException(error); } return responseContent; + }finally { + httpGet.releaseConnection(); } } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java index 1ab1ad7e..1613c96c 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java @@ -1,24 +1,17 @@ package me.chanjar.weixin.common.util.http; -import java.io.IOException; - import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.exception.WxErrorException; import org.apache.http.Consts; import org.apache.http.HttpHost; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; + +import java.io.IOException; /** * 简单的POST请求执行器,请求的参数是String, 返回的结果也是String @@ -47,6 +40,8 @@ public class SimplePostRequestExecutor implements RequestExecutor groupGet() throws WxErrorException { String url = "https://api.weixin.qq.com/cgi-bin/groups/get"; - String responseContent = execute(new JoddGetRequestExecutor(), url, null); + String responseContent = execute(new SimpleGetRequestExecutor(), url, null); /* * 操蛋的微信API,创建时返回的是 { group : { id : ..., name : ...} } * 查询时返回的是 { groups : [ { id : ..., name : ..., count : ... }, ... ] } @@ -438,14 +386,14 @@ public class WxMpServiceImpl implements WxMpService { String url = "https://api.weixin.qq.com/cgi-bin/groups/getid"; JsonObject o = new JsonObject(); o.addProperty("openid", openid); - String responseContent = execute(new JoddPostRequestExecutor(), url, o.toString()); + String responseContent = execute(new SimplePostRequestExecutor(), url, o.toString()); JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); return GsonHelper.getAsLong(tmpJsonElement.getAsJsonObject().get("groupid")); } public void groupUpdate(WxMpGroup group) throws WxErrorException { String url = "https://api.weixin.qq.com/cgi-bin/groups/update"; - execute(new JoddPostRequestExecutor(), url, group.toJson()); + execute(new SimplePostRequestExecutor(), url, group.toJson()); } public void userUpdateGroup(String openid, long to_groupid) throws WxErrorException { @@ -453,7 +401,7 @@ public class WxMpServiceImpl implements WxMpService { JsonObject json = new JsonObject(); json.addProperty("openid", openid); json.addProperty("to_groupid", to_groupid); - execute(new JoddPostRequestExecutor(), url, json.toString()); + execute(new SimplePostRequestExecutor(), url, json.toString()); } public void userUpdateRemark(String openid, String remark) throws WxErrorException { @@ -461,19 +409,19 @@ public class WxMpServiceImpl implements WxMpService { JsonObject json = new JsonObject(); json.addProperty("openid", openid); json.addProperty("remark", remark); - execute(new JoddPostRequestExecutor(), url, json.toString()); + execute(new SimplePostRequestExecutor(), url, json.toString()); } public WxMpUser userInfo(String openid, String lang) throws WxErrorException { String url = "https://api.weixin.qq.com/cgi-bin/user/info"; lang = lang == null ? "zh_CN" : lang; - String responseContent = execute(new JoddGetRequestExecutor(), url, "openid=" + openid + "&lang=" + lang); + String responseContent = execute(new SimpleGetRequestExecutor(), url, "openid=" + openid + "&lang=" + lang); return WxMpUser.fromJson(responseContent); } public WxMpUserList userList(String next_openid) throws WxErrorException { String url = "https://api.weixin.qq.com/cgi-bin/user/get"; - String responseContent = execute(new JoddGetRequestExecutor(), url, next_openid == null ? null : "next_openid=" + next_openid); + String responseContent = execute(new SimpleGetRequestExecutor(), url, next_openid == null ? null : "next_openid=" + next_openid); return WxMpUserList.fromJson(responseContent); } @@ -489,7 +437,7 @@ public class WxMpServiceImpl implements WxMpService { scene.addProperty("scene_id", scene_id); actionInfo.add("scene", scene); json.add("action_info", actionInfo); - String responseContent = execute(new JoddPostRequestExecutor(), url, json.toString()); + String responseContent = execute(new SimplePostRequestExecutor(), url, json.toString()); return WxMpQrCodeTicket.fromJson(responseContent); } @@ -502,7 +450,7 @@ public class WxMpServiceImpl implements WxMpService { scene.addProperty("scene_id", scene_id); actionInfo.add("scene", scene); json.add("action_info", actionInfo); - String responseContent = execute(new JoddPostRequestExecutor(), url, json.toString()); + String responseContent = execute(new SimplePostRequestExecutor(), url, json.toString()); return WxMpQrCodeTicket.fromJson(responseContent); } @@ -515,7 +463,7 @@ public class WxMpServiceImpl implements WxMpService { scene.addProperty("scene_str", scene_str); actionInfo.add("scene", scene); json.add("action_info", actionInfo); - String responseContent = execute(new JoddPostRequestExecutor(), url, json.toString()); + String responseContent = execute(new SimplePostRequestExecutor(), url, json.toString()); return WxMpQrCodeTicket.fromJson(responseContent); } @@ -529,14 +477,14 @@ public class WxMpServiceImpl implements WxMpService { JsonObject o = new JsonObject(); o.addProperty("action", "long2short"); o.addProperty("long_url", long_url); - String responseContent = execute(new JoddPostRequestExecutor(), url, o.toString()); + String responseContent = execute(new SimplePostRequestExecutor(), url, o.toString()); JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); return tmpJsonElement.getAsJsonObject().get("short_url").getAsString(); } public String templateSend(WxMpTemplateMessage templateMessage) throws WxErrorException { String url = "https://api.weixin.qq.com/cgi-bin/message/template/send"; - String responseContent = execute(new JoddPostRequestExecutor(), url, templateMessage.toJson()); + String responseContent = execute(new SimplePostRequestExecutor(), url, templateMessage.toJson()); JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); final JsonObject jsonObject = tmpJsonElement.getAsJsonObject(); if (jsonObject.get("errcode").getAsInt() == 0) @@ -546,7 +494,7 @@ public class WxMpServiceImpl implements WxMpService { public WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException { String url = "https://api.weixin.qq.com/semantic/semproxy/search"; - String responseContent = execute(new JoddPostRequestExecutor(), url, semanticQuery.toJson()); + String responseContent = execute(new SimplePostRequestExecutor(), url, semanticQuery.toJson()); return WxMpSemanticQueryResult.fromJson(responseContent); } @@ -578,7 +526,7 @@ public class WxMpServiceImpl implements WxMpService { url += "&grant_type=authorization_code"; try { - RequestExecutor executor = new JoddGetRequestExecutor(); + RequestExecutor executor = new SimpleGetRequestExecutor(); String responseText = executor.execute(getHttpclient(), httpProxy, url, null); return WxMpOAuth2AccessToken.fromJson(responseText); } catch (ClientProtocolException e) { @@ -596,7 +544,7 @@ public class WxMpServiceImpl implements WxMpService { url += "&refresh_token=" + refreshToken; try { - RequestExecutor executor = new JoddGetRequestExecutor(); + RequestExecutor executor = new SimpleGetRequestExecutor(); String responseText = executor.execute(getHttpclient(), httpProxy, url, null); return WxMpOAuth2AccessToken.fromJson(responseText); } catch (ClientProtocolException e) { @@ -618,7 +566,7 @@ public class WxMpServiceImpl implements WxMpService { } try { - RequestExecutor executor = new JoddGetRequestExecutor(); + RequestExecutor executor = new SimpleGetRequestExecutor(); String responseText = executor.execute(getHttpclient(), httpProxy, url, null); return WxMpUser.fromJson(responseText); } catch (ClientProtocolException e) { @@ -635,7 +583,7 @@ public class WxMpServiceImpl implements WxMpService { url += "&openid=" + oAuth2AccessToken.getOpenId(); try { - RequestExecutor executor = new JoddGetRequestExecutor(); + RequestExecutor executor = new SimpleGetRequestExecutor(); executor.execute(getHttpclient(), httpProxy, url, null); } catch (ClientProtocolException e) { throw new RuntimeException(e); @@ -688,11 +636,11 @@ public class WxMpServiceImpl implements WxMpService { } public String get(String url, String queryParam) throws WxErrorException { - return execute(new JoddGetRequestExecutor(), url, queryParam); + return execute(new SimpleGetRequestExecutor(), url, queryParam); } public String post(String url, String postData) throws WxErrorException { - return execute(new JoddPostRequestExecutor(), url, postData); + return execute(new SimplePostRequestExecutor(), url, postData); } /** @@ -772,36 +720,25 @@ public class WxMpServiceImpl implements WxMpService { public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { this.wxMpConfigStorage = wxConfigProvider; - String http_proxy_host = wxMpConfigStorage.getHttp_proxy_host(); - int http_proxy_port = wxMpConfigStorage.getHttp_proxy_port(); - String http_proxy_username = wxMpConfigStorage.getHttp_proxy_username(); - String http_proxy_password = wxMpConfigStorage.getHttp_proxy_password(); - - final HttpClientBuilder builder = HttpClients.custom(); - if (StringUtils.isNotBlank(http_proxy_host)) { - // 使用代理服务器 - if (StringUtils.isNotBlank(http_proxy_username)) { - // 需要用户认证的代理服务器 - CredentialsProvider credsProvider = new BasicCredentialsProvider(); - credsProvider.setCredentials( - new AuthScope(http_proxy_host, http_proxy_port), - new UsernamePasswordCredentials(http_proxy_username, http_proxy_password)); - builder - .setDefaultCredentialsProvider(credsProvider); - } else { - // 无需用户认证的代理服务器 - } - httpProxy = new HttpHost(http_proxy_host, http_proxy_port); + ApacheHttpClientBuilder apacheHttpClientBuilder = wxMpConfigStorage.getApacheHttpClientBuilder(); + if (null == apacheHttpClientBuilder) { + apacheHttpClientBuilder = DefaultApacheHttpHttpClientBuilder.get(); } + apacheHttpClientBuilder.httpProxyHost(wxMpConfigStorage.getHttp_proxy_host()) + .httpProxyPort(wxMpConfigStorage.getHttp_proxy_port()) + .httpProxyUsername(wxMpConfigStorage.getHttp_proxy_username()) + .httpProxyPassword(wxMpConfigStorage.getHttp_proxy_password()); + if (wxConfigProvider.getSSLContext() != null){ SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( wxConfigProvider.getSSLContext(), new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); - builder.setSSLSocketFactory(sslsf); + apacheHttpClientBuilder.sslConnectionSocketFactory(sslsf); } - httpClient = builder.build(); + + httpClient = apacheHttpClientBuilder.build(); } @Override @@ -865,6 +802,8 @@ public class WxMpServiceImpl implements WxMpService { return wxMpPrepayIdResult; } catch (IOException e) { throw new RuntimeException("Failed to get prepay id due to IO exception.", e); + }finally { + httpPost.releaseConnection(); } } @@ -927,6 +866,7 @@ public class WxMpServiceImpl implements WxMpService { payInfo.put("nonceStr", System.currentTimeMillis() + ""); payInfo.put("package", "prepay_id=" + prepayId); payInfo.put("signType", "MD5"); + payInfo.put("code_url",wxMpPrepayIdResult.getCode_url()); String finalSign = WxCryptUtil.createSign(payInfo, wxMpConfigStorage.getPartnerKey()); payInfo.put("paySign", finalSign); @@ -1037,6 +977,8 @@ public class WxMpServiceImpl implements WxMpService { error.setErrorCode(-1); error.setErrorMsg("incorrect response."); throw new WxErrorException(error); + }finally { + httpPost.releaseConnection(); } } @@ -1082,6 +1024,8 @@ public class WxMpServiceImpl implements WxMpService { WxError error = new WxError(); error.setErrorCode(-1); throw new WxErrorException(error); + }finally { + httpPost.releaseConnection(); } } @@ -1120,7 +1064,7 @@ public class WxMpServiceImpl implements WxMpService { synchronized (globalCardApiTicketRefreshLock) { if (wxMpConfigStorage.isCardApiTicketExpired()) { String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card"; - String responseContent = execute(new JoddGetRequestExecutor(), url, null); + String responseContent = execute(new SimpleGetRequestExecutor(), url, null); JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); String cardApiTicket = tmpJsonObject.get("ticket").getAsString(); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialDeleteRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialDeleteRequestExecutor.java index 8e7c41de..751261bf 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialDeleteRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialDeleteRequestExecutor.java @@ -34,13 +34,16 @@ public class MaterialDeleteRequestExecutor implements RequestExecutor params = new HashMap<>(); params.put("media_id", materialId); httpPost.setEntity(new StringEntity(WxGsonBuilder.create().toJson(params))); - CloseableHttpResponse response = httpclient.execute(httpPost); - String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } else { - return true; + try(CloseableHttpResponse response = httpclient.execute(httpPost)){ + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } else { + return true; + } + }finally { + httpPost.releaseConnection(); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialNewsInfoRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialNewsInfoRequestExecutor.java index e23ecc50..fb77b54d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialNewsInfoRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialNewsInfoRequestExecutor.java @@ -35,14 +35,18 @@ public class MaterialNewsInfoRequestExecutor implements RequestExecutor params = new HashMap<>(); params.put("media_id", materialId); httpPost.setEntity(new StringEntity(WxGsonBuilder.create().toJson(params))); - CloseableHttpResponse response = httpclient.execute(httpPost); - String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } else { - return WxMpGsonBuilder.create().fromJson(responseContent, WxMpMaterialNews.class); + try(CloseableHttpResponse response = httpclient.execute(httpPost)){ + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } else { + return WxMpGsonBuilder.create().fromJson(responseContent, WxMpMaterialNews.class); + } + }finally { + httpPost.releaseConnection(); } + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialUploadRequestExecutor.java index dcd4ef8e..5e90c07a 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialUploadRequestExecutor.java @@ -35,7 +35,6 @@ public class MaterialUploadRequestExecutor implements RequestExecutor params = new HashMap<>(); params.put("media_id", materialId); httpPost.setEntity(new StringEntity(WxGsonBuilder.create().toJson(params))); - CloseableHttpResponse response = httpclient.execute(httpPost); - String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } else { - return WxMpMaterialVideoInfoResult.fromJson(responseContent); + try(CloseableHttpResponse response = httpclient.execute(httpPost)){ + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } else { + return WxMpMaterialVideoInfoResult.fromJson(responseContent); + } + }finally { + httpPost.releaseConnection(); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java index 72917a93..a26f3520 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java @@ -44,22 +44,25 @@ public class MaterialVoiceAndImageDownloadRequestExecutor implements RequestExec Map params = new HashMap<>(); params.put("media_id", materialId); httpPost.setEntity(new StringEntity(WxGsonBuilder.create().toJson(params))); - CloseableHttpResponse response = httpclient.execute(httpPost); - // 下载媒体文件出错 - InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response); - byte[] responseContent = IOUtils.toByteArray(inputStream); - String responseContentString = new String(responseContent, "UTF-8"); - if (responseContentString.length() < 100) { - try { - WxError wxError = WxGsonBuilder.create().fromJson(responseContentString, WxError.class); - if (wxError.getErrorCode() != 0) { - throw new WxErrorException(wxError); + try(CloseableHttpResponse response = httpclient.execute(httpPost)){ + // 下载媒体文件出错 + InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response); + byte[] responseContent = IOUtils.toByteArray(inputStream); + String responseContentString = new String(responseContent, "UTF-8"); + if (responseContentString.length() < 100) { + try { + WxError wxError = WxGsonBuilder.create().fromJson(responseContentString, WxError.class); + if (wxError.getErrorCode() != 0) { + throw new WxErrorException(wxError); + } + } catch (com.google.gson.JsonSyntaxException ex) { + return new ByteArrayInputStream(responseContent); } - } catch (com.google.gson.JsonSyntaxException ex) { - return new ByteArrayInputStream(responseContent); } + return new ByteArrayInputStream(responseContent); + }finally { + httpPost.releaseConnection(); } - return new ByteArrayInputStream(responseContent); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java index 12606096..bde25cfb 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java @@ -58,8 +58,9 @@ public class QrCodeRequestExecutor implements RequestExecutor