From e407021386b0fc4d9a23aed45d957bec086a8f60 Mon Sep 17 00:00:00 2001 From: liyi Date: Fri, 25 Mar 2016 16:49:09 +0800 Subject: [PATCH] 2.6.3 --- changelog.txt | 7 ++ pom.xml | 2 +- .../popular/client/HttpClientFactory.java | 83 ++++++++++++++++++- 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/changelog.txt b/changelog.txt index 37acc9d9..a8f2e573 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,13 @@ WEIXIN-POPULAR CHANGELOG =========================== https://github.com/liyiorg/weixin-popular +Changes in version 2.6.3 (2016-03-25) +------------------------------------- +* weixin.popular.client.HttpClientFactory 修改 +* 增加请求超时设置,默认5秒。 +* 增加异常请求重试,默认失败重试2次。 + + Changes in version 2.6.2 (2016-03-10) ------------------------------------- * weixin.popular.api.MediaAPI bug 修复 diff --git a/pom.xml b/pom.xml index 3ad4b33d..1546a400 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 weixin weixin-popular - 2.6.2-RELEASE + 2.6.3-RELEASE https://github.com/liyiorg/weixin-popular diff --git a/src/main/java/weixin/popular/client/HttpClientFactory.java b/src/main/java/weixin/popular/client/HttpClientFactory.java index 6b964924..f10ba24f 100644 --- a/src/main/java/weixin/popular/client/HttpClientFactory.java +++ b/src/main/java/weixin/popular/client/HttpClientFactory.java @@ -1,5 +1,8 @@ package weixin.popular.client; +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; @@ -7,12 +10,21 @@ import java.security.UnrecoverableKeyException; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLException; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpRequest; +import org.apache.http.client.HttpRequestRetryHandler; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.config.SocketConfig; +import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.BasicHttpClientConnectionManager; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.protocol.HttpContext; /** * httpclient 4.3.x @@ -22,12 +34,24 @@ public class HttpClientFactory{ private static final String[] supportedProtocols = new String[]{"TLSv1"}; + + private static int timeout = 5000; //socket time out (default 5 s) + + private static int retryExecutionCount = 2; //HttpClient retry execution count. + public static CloseableHttpClient createHttpClient() { try { SSLContext sslContext = SSLContexts.custom().useSSL().build(); + BasicHttpClientConnectionManager connMrg = new BasicHttpClientConnectionManager(); + SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(timeout).build(); + connMrg.setSocketConfig(socketConfig); SSLConnectionSocketFactory sf = new SSLConnectionSocketFactory(sslContext,SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - return HttpClientBuilder.create().setSSLSocketFactory(sf).build(); + return HttpClientBuilder.create() + .setConnectionManager(connMrg) + .setSSLSocketFactory(sf) + .setRetryHandler(new HttpRequestRetryHandlerImpl()) + .build(); } catch (KeyManagementException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { @@ -43,9 +67,12 @@ public static CloseableHttpClient createHttpClient(int maxTotal,int maxPerRoute) PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(); poolingHttpClientConnectionManager.setMaxTotal(maxTotal); poolingHttpClientConnectionManager.setDefaultMaxPerRoute(maxPerRoute); + SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(timeout).build(); + poolingHttpClientConnectionManager.setDefaultSocketConfig(socketConfig); return HttpClientBuilder.create() .setConnectionManager(poolingHttpClientConnectionManager) .setSSLSocketFactory(sf) + .setRetryHandler(new HttpRequestRetryHandlerImpl()) .build(); } catch (KeyManagementException e) { e.printStackTrace(); @@ -77,7 +104,12 @@ public static CloseableHttpClient createKeyMaterialHttpClient(KeyStore keystore, SSLContext sslContext = SSLContexts.custom().useSSL().loadKeyMaterial(keystore, keyPassword.toCharArray()).build(); SSLConnectionSocketFactory sf = new SSLConnectionSocketFactory(sslContext,supportedProtocols, null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); - return HttpClientBuilder.create().setSSLSocketFactory(sf).build(); + SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(timeout).build(); + return HttpClientBuilder.create() + .setDefaultSocketConfig(socketConfig) + .setSSLSocketFactory(sf) + .setRetryHandler(new HttpRequestRetryHandlerImpl()) + .build(); } catch (KeyManagementException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { @@ -90,5 +122,52 @@ public static CloseableHttpClient createKeyMaterialHttpClient(KeyStore keystore, return null; } + public static void setTimeout(int timeout) { + HttpClientFactory.timeout = timeout; + } + public static void setRetryExecutionCount(int retryExecutionCount) { + HttpClientFactory.retryExecutionCount = retryExecutionCount; + } + + + /** + * + * HttpClient 超时重试 + * @author LiYi + */ + private static class HttpRequestRetryHandlerImpl implements HttpRequestRetryHandler{ + + @Override + public boolean retryRequest( + IOException exception, + int executionCount, + HttpContext context) { + if (executionCount > retryExecutionCount) { + return false; + } + if (exception instanceof InterruptedIOException) { + return false; + } + if (exception instanceof UnknownHostException) { + return false; + } + if (exception instanceof ConnectTimeoutException) { + return true; + } + if (exception instanceof SSLException) { + return false; + } + HttpClientContext clientContext = HttpClientContext.adapt(context); + HttpRequest request = clientContext.getRequest(); + boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); + if (idempotent) { + // Retry if the request is considered idempotent + return true; + } + return false; + } + + }; + }