Статья

HttpClient – отправка собственных Cookie

В этой короткой статье основное внимание будет уделено тому, как отправить пользовательский Cookie с помощью Apache HttpClient.

HttpClient после версии 4.3

В новой версии HttpClient 4.3 мы будем использовать API билдера, отвечающего как за создание, так и за настройку клиента.
Во-первых, нам нужно будет создать хранилище cookie и настроить наш образец cookie в хранилище:
BasicCookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("SESSIONID", "4567");
cookie.setDomain(".github.com");
cookie.setPath("/");
cookieStore.addCookie(cookie);
Мы можем назначить это хранилище cookie для HttpClient с помощью метода setDefaultCookieStore() и отправить запрос:
@Test
public void thenCookieSentCorrectly() 
  throws ClientProtocolException, IOException {
    BasicCookieStore cookieStore = new BasicCookieStore();
    BasicClientCookie cookie = new BasicClientCookie("SESSIONID", "4567");
    cookie.setDomain(".github.com");
    cookie.setPath("/");
    cookieStore.addCookie(cookie);
    HttpClient client = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build();

    final HttpGet request = new HttpGet("http://www.github.com");

    response = client.execute(request);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}
Очень важным элементом является домен, устанавливаемый в cookie – без установки правильного домена клиент вообще не отправит cookie!

Кроме того, в зависимости от используемой версии, также может потребоваться установить дополнительный атрибут:
cookie.setAttribute(ClientCookie.DOMAIN_ATTR, "true");

HttpClient до версии 4.3

С более старыми версиями HttpClient (до версии 4.3) хранилище cookie нужно устанавливать непосредственно в HttpClient:
@Test
public void whenSettingCookiesOnTheHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    BasicCookieStore cookieStore = new BasicCookieStore();
    BasicClientCookie cookie = new BasicClientCookie("SESSIONID", "4567");
    cookie.setDomain(".github.com");
    cookie.setPath("/");
    cookieStore.addCookie(cookie);
    DefaultHttpClient client = new DefaultHttpClient();
    client.setCookieStore(cookieStore);

    HttpGet request = new HttpGet("http://www.github.com");

    response = client.execute(request);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}
Кроме способа построения Http клиента, других отличий от предыдущего примера нет.

Установка cookie в объекте Request

Если установка cookie для всего HttpClient невозможна, мы можем настроить запросы с помощью cookie по отдельности, используя класс HttpContext:
@Test
public void whenSettingCookiesOnTheRequest_thenCookieSentCorrectly() 
  throws ClientProtocolException, IOException {
    BasicCookieStore cookieStore = new BasicCookieStore();
    BasicClientCookie cookie = new BasicClientCookie("SESSIONID", "4567");
    cookie.setDomain(".github.com");
    cookie.setPath("/");
    cookieStore.addCookie(cookie);
    instance = HttpClientBuilder.create().build();

    HttpGet request = new HttpGet("http://www.github.com");

    HttpContext localContext = new BasicHttpContext();
    localContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
    // до версии 4.3: localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); 

    response = instance.execute(request, localContext);

    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}

Установка cookie для низкоуровневых запросов

Низкоуровневой альтернативой установки cookie в HTTP запросе была бы установка его в качестве raw-заголовка:
@Test
public void whenSettingCookiesOnARequest() 
  throws ClientProtocolException, IOException {
    instance = HttpClientBuilder.create().build();
    HttpGet request = new HttpGet("http://www.github.com");
    request.setHeader("Cookie", "SESSIONID=4567");

    response = instance.execute(request);

    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}
Это, конечно, более подвержено ошибкам, чем работа со встроенной поддержкой cookie. Обратите внимание, что в этом случае мы больше не устанавливаем домен, что неправильно.

Заключение

В этой статье мы кратко рассказали, как установить пользовательский cookie в HttpClient
java