Apache HttpClient 4.5 HttpRequestRetryHandler Example
In the following example we show how to create a custom HttpRequestRetryHandler
in order to enable a custom exception recovery mechanism.
When using this interface, we need to implement the retryRequest
method. This allows us to define a custom retry count mechanism and exception recovery mechanism. Take a look at the following tutorial.
Maven dependencies
We use maven to manage our dependencies and are using Apache HttpClient version 4.5. Add the following dependency to your project.
<?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.memorynotfound.apache.httpclient</groupId>
<artifactId>retry-handler</artifactId>
<version>1.0.0-SNAPSHOT</version>
<url>https://memorynotfound.com</url>
<name>httpclient - ${project.artifactId}</name>
<dependencies>
<!-- Apache HttpClient -->
<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 Example
We implement the HttpRequestRetryHandler
interface for a custom retry -and exception recovery mechanism. This allows us to keep track of how many times a request will been sent, before we are handling it to the corresponding exception mechanism.
package com.memorynotfound.httpclient;
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;
};
}
}
Output
The previous application prints the following messages to the console. As you can see, the application tries 5 times to execute the request, before giving up and throwing an HttpHostConnectException
.
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