Course – LS (cat=HTTP Client-Side)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

This tutorial will focus on how to send a Custom Cookie using the Apache HttpClient.

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.

2. Configure Cookie Management on the HttpClient

2.1. HttpClient After 4.3

In the newer HttpClient 4.3, we’ll leverage the fluent builder API responsible with both constructing and configuring the client.

First, we’ll need to create a cookie store and set up our sample cookie in the store:

BasicCookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", "1234");
cookie.setDomain(".github.com");
cookie.setPath("/");
cookieStore.addCookie(cookie);

Then, we can set up this cookie store on the HttpClient using the setDefaultCookieStore() method and send the request:

@Test
final void whenSettingCookiesOnTheHttpClient_thenCookieSentCorrectly() throws IOException {
    final BasicCookieStore cookieStore = new BasicCookieStore();
    final BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", "1234");
    cookie.setDomain(".github.com");
    cookie.setAttribute("domain", "true");
    cookie.setPath("/");
    cookieStore.addCookie(cookie);
    final HttpGet request = new HttpGet("http://www.github.com");

    try (CloseableHttpClient client = HttpClientBuilder.create()
        .setDefaultCookieStore(cookieStore)
        .build();

        CloseableHttpResponse response = (CloseableHttpResponse) client
            .execute(request, new CustomHttpClientResponseHandler())) {
        assertThat(response.getCode(), equalTo(200));
    }

}

A very important element is the domain being set on the cookie – without setting the proper domain, the client will not send the cookie at all!

Also, depending on the exact version you use, you may also need to set:

cookie.setAttribute("domain", "true");

2.2. HttpClient Before 4.3

With older versions of the HttpClient (before 4.3) – the cookie store was set directly on the HttpClient:

@Test
public void givenUsingDeprecatedApi_whenSettingCookiesOnTheHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    BasicCookieStore cookieStore = new BasicCookieStore();
    BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", "1234");
    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));
}

Other than the way the client is built, there’s no other difference from the previous example.

If setting the cookie on the entire HttpClient is not an option, we can configure requests with the cookie individually using the HttpContext class:

@Test
final void whenSettingCookiesOnTheHttpClient_thenCookieSentCorrectly() throws IOException {
    final BasicCookieStore cookieStore = new BasicCookieStore();
    final BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", "1234");
    cookie.setDomain(".github.com");
    cookie.setAttribute("domain", "true");
    cookie.setPath("/");
    cookieStore.addCookie(cookie);
    final HttpGet request = new HttpGet("http://www.github.com");

    try (CloseableHttpClient client = HttpClientBuilder.create()
        .setDefaultCookieStore(cookieStore)
        .build();

        CloseableHttpResponse response = (CloseableHttpResponse) client
            .execute(request, new CustomHttpClientResponseHandler())) {
        assertThat(response.getCode(), equalTo(200));
    }

}

A low level alternative of setting the cookie on the HTTP Request would be setting it as a raw Header:

@Test
final void whenSettingCookiesOnARequest_thenCorrect() throws IOException {
    final HttpGet request = new HttpGet("http://www.github.com");
    request.setHeader("Cookie", "JSESSIONID=1234");
    try (CloseableHttpClient client = HttpClients.createDefault();

        CloseableHttpResponse response = (CloseableHttpResponse) client
            .execute(request, new CustomHttpClientResponseHandler())) {
        assertThat(response.getCode(), equalTo(200));
    }
}

This is of course much more error-prone than working with the built in cookie support. For example, notice that we’re no longer setting the domain in this case – which is not correct.

5. Conclusion

This article illustrated how to work with the HttpClient to send a custom, user controlled Cookie.

Note that this is not the same as letting the HttpClient deal with the cookies set by a server. Instead, it’s controlling the client side manually at a low level.

The implementation of all these examples and code snippets can be found in my github project.

Course – LS (cat=HTTP Client-Side)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – HTTP Client (eBook) (cat=Http Client-Side)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.