How do I retry failed requests using Java 11 HttpClient?

Retrying failed requests using Java 11’s HttpClient involves implementing a custom retry mechanism. Java 11’s HttpClient doesn’t provide native support for automatic retries, but you can build a retry mechanism into your application by wrapping the logic in a loop.

Here’s how you can do it step by step:

1. Define a Retry Mechanism

You’ll need to decide on:

  • The maximum number of retry attempts.
  • An optional delay between retries.
  • The type of failures that should trigger retries (e.g., IOException).

2. Create a Function to Retry Requests

You can encapsulate the retry logic in a utility method or by using a loop.

3. Full Code Example:

Below is an example implementation:

package org.kodejava.net.http;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.io.IOException;

public class HttpClientWithRetry {

   public static void main(String[] args) {
      HttpClient httpClient = HttpClient.newHttpClient();
      HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create("https://api.example.com/resource"))
              .timeout(Duration.ofSeconds(10))
              .GET()
              .build();

      int maxRetries = 3;  // Max number of retries
      Duration delay = Duration.ofSeconds(2); // Delay between retries

      try {
         HttpResponse<String> response = sendWithRetries(httpClient, request, maxRetries, delay);
         System.out.println("Response received: " + response.body());
      } catch (Exception e) {
         System.err.println("Request failed after retries: " + e.getMessage());
      }
   }

   public static HttpResponse<String> sendWithRetries(HttpClient client,
                                                      HttpRequest request,
                                                      int maxRetries,
                                                      Duration delay) throws Exception {
      int attempts = 0;

      while (true) {
         try {
            // Attempt to send the request
            return client.send(request, HttpResponse.BodyHandlers.ofString());
         } catch (IOException | InterruptedException ex) {
            attempts++;
            if (attempts > maxRetries) {
               throw new Exception("Maximum retry attempts reached.", ex);
            }
            System.out.println("Request failed, retrying... (" + attempts + "/" + maxRetries + ")");
            Thread.sleep(delay.toMillis()); // Delay before retry
         }
      }
   }
}

Explanation:

  1. HttpClient Initialization:
    • The HttpClient is created using HttpClient.newHttpClient().
  2. Retry Logic:
    • The sendWithRetries method sends the HTTP request and retries on exceptions (IOException or InterruptedException in this example).
    • A loop tracks the number of attempts and retries until either the request succeeds or the maximum retry limit is reached.
  3. Delay Between Retries:
    • A Thread.sleep introduces a delay (defined by a Duration object) between retries.
  4. Failure Handling:
    • If all retries fail, an exception is thrown indicating the request could not be completed.
  5. Configurations:
    • You can adjust the retry count, delay, and consider making the logic more robust by checking specific HTTP status codes for retries (e.g., 5xx server errors).

Future Improvements:

  • Exponential Backoff: Increase the delay between retries exponentially to ease server load.
  • Timeout Handling: Handle custom timeout scenarios with detailed configuration.
  • Customizable Errors: Customize retry logic based on specific HTTP response codes (e.g., retry only for 500–599 responses).

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.