1. 概述

这篇简短教程将展示如何配置 Apache HttpClient 以自动跟随 POST 请求的重定向。

如果你想深入了解更多 HttpClient 的酷炫用法,可以参考 **HttpClient 主教程**。

2. HTTP POST 请求的重定向

2.1. HttpClient 5.x 版本

在 HttpClient 5.x 中,默认情况下,无论是 GET 还是 POST 请求,只要遇到重定向都会自动跟随。这个行为与之前的版本(4.5.x)不同,我们将在下一节展示旧版本的行为。

@Test
void givenRedirectingPOST_whenUsingDefaultRedirectStrategy_thenRedirected() throws IOException {

    final HttpPost request = new HttpPost("http://t.co/I5YYd9tddw");

    try (CloseableHttpClient httpClient = HttpClientBuilder.create()
        .setRedirectStrategy(new DefaultRedirectStrategy())
        .build()) {
        httpClient.execute(request, response -> {
            assertThat(response.getCode(), equalTo(200));
            return response;
        });
    }
}

注意,使用 DefaultRedirectStrategy 时,重定向会通过 POST 方法跟随,最终得到 200 OK 状态码。

即使我们不显式设置 new DefaultRedirectStrategy(),重定向也会被跟随:

@Test
void givenRedirectingPOST_whenConsumingUrlWhichRedirectsWithPOST_thenRedirected() throws IOException {

    final HttpPost request = new HttpPost("http://t.co/I5YYd9tddw");

    try (CloseableHttpClient httpClient = HttpClientBuilder.create()
        .build()) {
        httpClient.execute(request, response -> {
            assertThat(response.getCode(), equalTo(200));
            return response;
        });
    }
}

2.2. HttpClient 4.5 版本

在 HttpClient 4.5 中,默认情况下,只有 GET 请求的重定向会被自动跟随。如果 POST 请求收到 HTTP 301 Moved Permanently302 Found 响应,重定向不会自动跟随

这是由 HTTP RFC 2616 规定的:

如果在非 GET 或 HEAD 请求的响应中收到 301 状态码,用户代理不得自动重定向请求,除非得到用户确认,因为这可能会改变请求发出的条件。

当然,有些场景下我们需要改变这种行为,放宽严格的 HTTP 规范。

首先,我们看看默认行为:

@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));
}

如你所见,默认情况下不会跟随重定向,我们得到的是 301 状态码

现在,我们看看如何通过设置重定向策略来跟随重定向:

@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));
}

使用 LaxRedirectStrategy 时,HTTP 的限制被放宽,POST 请求的重定向也会被跟随,最终得到 200 OK 状态码。

3. 总结

这篇简短指南展示了如何配置任意版本的 Apache HttpClient,使其也能跟随 POST 请求的重定向——放宽了严格的 HTTP 标准。


原始标题:Apache HttpClient – Follow Redirects for POST | Baeldung