HttpClient 4 – Follow Redirects for POST

1. Overview

This quick tutorial will show how to configure the Apache HttpClient 4 to automatically follow redirects for POST requests.

If you want to dig deeper and learn other cool things you can do with the HttpClient – head on over to the main HttpClient tutorial.

By default, only GET requests resulting in a redirect are automatically followed. If a POST requests is answered with either HTTP 301 Moved Permanently or with 302 Found – the redirect is not automatically followed.

This is specified by the HTTP RFC 2616:

If the 301 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.

There are of course usecases where we need to change that behavior and relax the strict HTTP specification.

First, let’s check the default behavior:

@Test
public void givenPostRequest_whenConsumingUrlWhichRedirects_thenNotRedirected() 
  throws ClientProtocolException, IOException {
    HttpClient instance = HttpClientBuilder.create().build();
    HttpResponse response = instance.execute(new HttpPost("http://t.co/I5YYd9tddw"));
    assertThat(response.getStatusLine().getStatusCode(), equalTo(301));
}

As you can see, the redirect is not followed by default, and we get back the 301 Status Code.

2. Redirecting on HTTP POST

2.1. For HttpClient 4.3 and After

In HttpClient 4.3, a higher level API has been introduced for both creation and configuration of the client:

@Test
public void givenRedirectingPOST_whenConsumingUrlWhichRedirectsWithPOST_thenRedirected() 
  throws ClientProtocolException, IOException {
    HttpClient instance = 
      HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();
    HttpResponse response = instance.execute(new HttpPost("http://t.co/I5YYd9tddw"));
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}

Notice the HttpClientBuilder is now the starting point of a fluent API which allows full configuration of the client in a more readable way than before.

2.2. For HttpClient 4.2

In the previous version of HttpClient (4.2) we can configure the redirect strategy directly on the client:

@SuppressWarnings("deprecation")
@Test
public void givenRedirectingPOST_whenConsumingUrlWhichRedirectsWithPOST_thenRedirected() 
  throws ClientProtocolException, IOException {
    DefaultHttpClient client = new DefaultHttpClient();
    client.setRedirectStrategy(new LaxRedirectStrategy());

    HttpResponse response = client.execute(new HttpPost("http://t.co/I5YYd9tddw"));
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}

Notice that now, with the new LaxRedirectStrategy, the HTTP Restrictions are relaxed and the redirect is followed over POST as well – leading to a 200 OK status code.

2.3. Pre HttpClient 4.2

Before HttpClient 4.2, the LaxRedirectStrategy class didn’t exist, so we need to roll our own:

@Test
public void givenRedirectingPOST_whenConsumingUrlWhichRedirectsWithPOST_thenRedirected() 
  throws ClientProtocolException, IOException {
    DefaultHttpClient client = new DefaultHttpClient();
    client.setRedirectStrategy(new DefaultRedirectStrategy() {
        /** Redirectable methods. */
        private String[] REDIRECT_METHODS = new String[] { 
            HttpGet.METHOD_NAME, HttpPost.METHOD_NAME, HttpHead.METHOD_NAME 
        };

        @Override
        protected boolean isRedirectable(String method) {
            for (String m : REDIRECT_METHODS) {
                if (m.equalsIgnoreCase(method)) {
                    return true;
                }
            }
            return false;
        }
    });

    HttpResponse response = client.execute(new HttpPost("http://t.co/I5YYd9tddw"));
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}

3. Conclusion

This quick guide illustrated how to configure any version of the Apache HttpClient 4 to follow redirects for HTTP POST requests as well – relaxing the strict HTTP standard.

The implementation of all these examples and code snippets can be found in my github project – this is an Eclipse based project, so it should be easy to import and run as it is.

Related posts:

Java Program to Check whether Graph is a Bipartite using DFS
Binary Numbers in Java
Custom Thread Pools In Java 8 Parallel Streams
Hướng dẫn sử dụng Java Annotation
Java Program to Implement Levenshtein Distance Computing Algorithm
Introduction to Liquibase Rollback
Java Program to Implement Segment Tree
Quick Guide to java.lang.System
HashMap trong Java hoạt động như thế nào?
Java Program to Implement Bellman-Ford Algorithm
Java Program to Implement DelayQueue API
The Dining Philosophers Problem in Java
Request a Delivery / Read Receipt in Javamail
Java Program to Describe the Representation of Graph using Incidence Matrix
Java – Get Random Item/Element From a List
Spring Security Registration – Resend Verification Email
Java Program to Apply Above-Below-on Test to Find the Position of a Point with respect to a Line
Java Program to Implement the Program Used in grep/egrep/fgrep
Spring Boot Tutorial – Bootstrap a Simple Application
Jackson vs Gson
Introduction to Using FreeMarker in Spring MVC
Why String is Immutable in Java?
Java Program to Implement CountMinSketch
Updating your Password
Java Program to Implement Bucket Sort
Java Program to Implement Wagner and Fisher Algorithm for online String Matching
Vấn đề Nhà sản xuất (Producer) – Người tiêu dùng (Consumer) và đồng bộ hóa các luồng trong Java
Java Program to Implement Pollard Rho Algorithm
Java Program to Find the Longest Subsequence Common to All Sequences in a Set of Sequences
Java Scanner hasNext() vs. hasNextLine()
A Quick Guide to Spring Cloud Consul
Spring WebClient Filters