HttpClient 4 - Следуйте перенаправления для POST

HttpClient 4 - следуйте перенаправления для POST

1. обзор

В этом кратком руководстве показано, как настроить Apache HttpClient 4 для автоматического следования перенаправлениям для запросов POST.

Если вы хотите копнуть глубже и узнать о других интересных вещах, которые можно сделать с помощью HttpClient, перейдите кthe main HttpClient tutorial.

По умолчанию автоматически выполняются только запросы GET, приводящие к перенаправлению. Если на POST-запросы отвечаютHTTP 301 Moved Permanently или302 Found -the redirect is not automatically followed.

Это определяется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));
}

Как видите,the redirect is not followed by default, и мы возвращаем301 Status Code.

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

Обратите внимание наthe HttpClientBuilder is now the starting point of a 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 ослаблены иthe redirect is followed over POST as well - приводит к коду состояния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));
}

3. Заключение

В этом кратком руководстве показано, как настроить любую версию Apache HttpClient 4, чтобы она также следовала перенаправлениям для запросов HTTP POST - ослабляя строгий стандарт HTTP.

Реализация всех этих примеров и фрагментов кодаcan be found in my github project - это проект на основе Eclipse, поэтому его должно быть легко импортировать и запускать как есть.