最近使用到了HttpClient,看了一下官方文檔:HttpClient implementations are expected to be thread safe. It is recommended that the same instance of this class is reused for multiple request executions,翻譯過來的意思就是:HttpClient的實現是線程安全的,可以重用相同的實例來執行多次請求。遇到這種描述的話,我們就應該想到,需要對HttpClient來進行封裝了。由于是使用的spring boot,所以下面來結合spring boot來封裝HttpClient。
一、Request retry handler(請求重試處理)
為了使自定義異常機制生效,需要實現HttpRequestRetryHandler接口,代碼如下:
import java.io.IOException; import java.io.InterruptedIOException; import java.net.UnknownHostException; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.NoHttpResponseException; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.protocol.HttpContext; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 描述:HttpClient的重試處理機制 */ @Configuration public class MyhttpRequestRetryHandler { @Value("${httpclient.config.retryTime}")// 此處建議采用@ConfigurationProperties(prefix="httpclient.config")方式,方便復用 private int retryTime; @Bean public HttpRequestRetryHandler httpRequestRetryHandler() { // 請求重試 final int retryTime = this.retryTime; return new HttpRequestRetryHandler() { public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { // Do not retry if over max retry count,如果重試次數超過了retryTime,則不再重試請求 if (executionCount >= retryTime) { return false; } // 服務端斷掉客戶端的連接異常 if (exception instanceof NoHttpResponseException) { return true; } // time out 超時重試 if (exception instanceof InterruptedIOException) { return true; } // Unknown host if (exception instanceof UnknownHostException) { return false; } // Connection refused if (exception instanceof ConnectTimeoutException) { return false; } // SSL handshake exception if (exception instanceof SSLException) { return false; } HttpClientContext clientContext = HttpClientContext.adapt(context); HttpRequest request = clientContext.getRequest(); if (!(request instanceof HttpEntityEnclosingRequest)) { return true; } return false; } }; } }
二、Pooling connection manager(連接池管理)
PoolingHttpClientConnectionManager用來管理客戶端的連接池,并且可以為多個線程的請求提供服務,代碼如下:
新聞熱點
疑難解答