HttpClient HttpRequestRetryHandler示例
在以下示例中,我們演示瞭如何創建自定義HttpRequestRetryHandler
以啓用自定義異常恢復機制。 當使用這個接口時,需要實現retryRequest
方法。 這使我們能夠定義一個自定義的重試計數機制和異常恢復機制。 看看下面的教程是如何實現的。
Maven依賴關係
我們使用maven來管理依賴關係,並使用Apache HttpClient 4.5版本。 將以下依賴項添加到您的項目中。
pom.xml 文件的內容如下 -
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yiibai.httpclient.httmethods</groupId>
<artifactId>http-get</artifactId>
<version>1.0.0-SNAPSHOT</version>
<url>https://memorynotfound.com</url>
<name>httpclient - ${project.artifactId}</name>
<dependencies>
<!-- Apache Commons IO -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
HttpRequestRetryHandler示例
我們實現HttpRequestRetryHandler
接口來實現自定義重試和異常恢復機制。 這使我們能夠跟蹤發送請求的次數,然後再將其處理爲相應的異常機制。
文件:HttpClientRetryHandlerExample.java -
package com.yiibai.httpdemo;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import javax.net.ssl.SSLException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
/**
* This example demonstrates the use of {@link HttpRequestRetryHandler}.
*/
public class HttpClientRetryHandlerExample {
public static void main(String... args) throws IOException {
CloseableHttpClient httpclient = HttpClients.custom()
.setRetryHandler(retryHandler())
.build();
try {
HttpGet httpget = new HttpGet("http://localhost:1234");
System.out.println("Executing request " + httpget.getRequestLine());
httpclient.execute(httpget);
System.out.println("----------------------------------------");
System.out.println("Request finished");
} finally {
httpclient.close();
}
}
private static HttpRequestRetryHandler retryHandler(){
return (exception, executionCount, context) -> {
System.out.println("try request: " + executionCount);
if (executionCount >= 5) {
// Do not retry if over max retry count
return false;
}
if (exception instanceof InterruptedIOException) {
// Timeout
return false;
}
if (exception instanceof UnknownHostException) {
// Unknown host
return false;
}
if (exception instanceof SSLException) {
// SSL handshake exception
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;
};
}
}
執行上面示例代碼,得到以下結果 -
Executing request GET http://localhost:1234 HTTP/1.1
try request: 1
try request: 2
try request: 3
try request: 4
try request: 5
Exception in thread "main" org.apache.http.conn.HttpHostConnectException: Connect to localhost:1234 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:159)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:373)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:381)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
at com.yiibai.httpdemo.HttpClientRetryHandlerExample.main(HttpClientRetryHandlerExample.java:30)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:75)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
... 10 more