Apache HttpClient请求的重定向
Contents
1. 概述
本快速教程将展示如何配置 Apache HttpClient 以自动跟踪 POST 请求的重定向。
默认情况下,仅自动遵循导致重定向的 GET 请求。如果使用HTTP 301 Moved Permanently或302 Found响应 POST 请求,则不会自动遵循重定向。
这是由HTTP RFC 2616 指定的:
如果收到 301 状态代码以响应 GET 或 HEAD 以外的请求,用户代理不得自动重定向请求,除非用户可以确认,因为这可能会改变发出请求的条件。 当然,在某些用例中,我们需要改变这种行为并放宽严格的 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 状态码。
2. 在 HTTP POST 上重定向
2.1. 对于 HttpClient 4.3 及更高版本
在 HttpClient 4.3 中,为客户端的创建和配置引入了更高级别的 API:
@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));
}
请注意,**HttpClientBuilder现在是 fluent API 的起点,**它允许以比以前更易读的方式对客户端进行完整配置。
2.2. 对于 HttpClient 4.2
在之前版本的HttpClient(4.2)中我们可以直接在客户端配置重定向策略:
@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));
}
请注意,现在,使用新的LaxRedirectStrategy,放宽了 HTTP 限制,并且重定向也通过 POST 进行- 导致200 OK状态代码。
2.3. HttpClient 4.2 之前
在 HttpClient 4.2 之前,LaxRedirectStrategy类不存在,所以我们需要自己滚动:
@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));
}