I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

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

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 and send the request:

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

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!

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 is 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:

@Test
public void whenSettingCookiesOnTheRequest_thenCookieSentCorrectly() 
  throws ClientProtocolException, IOException {
    BasicCookieStore cookieStore = new BasicCookieStore();
    BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", "1234");
    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);
    // localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); // before 4.3
    response = instance.execute(request, localContext);

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

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

@Test
public void whenSettingCookiesOnARequest_thenCorrect() 
  throws ClientProtocolException, IOException {
    instance = HttpClientBuilder.create().build();
    HttpGet request = new HttpGet("http://www.github.com");
    request.setHeader("Cookie", "JSESSIONID=1234");

    response = instance.execute(request);

    assertThat(response.getStatusLine().getStatusCode(), 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 – but 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 – this is an Eclipse based project, so it should be easy to import and run as it is.

I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE LESSONS

Sort by:   newest | oldest | most voted
ThatGuy121
Guest

This is awesome, thanks very much!

Catalin
Guest

Cum as putea sa setez expiry date? Metoda accepta un obiect ca parametru, insa formatul de expiry date al unui cookie e de genul (zi, dd-mm-yyyy hh:mm:ss GMT). Multumesc.

Eugen Paraschiv
Guest

Hey Catalin, first – congrats – this is the very first comments in Romanian that I got in more than 3 years of running Baeldung 🙂
Now – while that’s cool, it’s also a bit problematic because most of the readers of the site don’t – as you can probably imagine – speak Romanian. So – please go ahead and rewrite it in English so that it can be understood by all readers. Cheers,
Eugen.

Catalin
Guest
I was asking how to set the expiry date on a BasicClientCookie. The cookie expiry date format is not the same as java’s default Date() format so I can’t pass a Date object as the method wants. Also there is no setExpiryDate(String arg) method so I can’t pass the date formatted through a SimpleDateFormat object. Anyhow, I actually found out there was no need to set up cookies manually (copy pasting from Developer Tools -> Network in browser and recreating manually the cookie object). If I create a localContext like in your example and bind a cookieStore to it, then… Read more »
Eugen Paraschiv
Guest

Hey Catalin – so, on the format of the cookie expiry date – if the standard API that accepts a Date doesn’t end up in a valid format (according to the spec) – then that’s a bug which needs to be raised on HttpClient. That API call – if working correctly – should definitely result in a valid expiry date format.
Yes – the cookie management happens automatically and there’s no need (usually) to manage it by hand – that is the right way to do it.
Cheers,
Eugen.

Max Romanovsky
Guest

I also had to add the following line to make `.example.com` (subdomain match) working:

cookie.setAttribute(ClientCookie.DOMAIN_ATTR, “.example.com”); //org.apache.http.impl.cookie.BasicDomainHandler#domainMatch

wpDiscuz