Search code examples
apache-httpclient-4.xapache-httpcomponentsapache-httpasyncclient

Apache HttpComponents CookieStore Not Storing Cookies


I'm using HttpComponents 4.5.2 and I'm trying to store cookies as I need to use them for login and other requests. The code works fine whilst the application is still running, but the problem here is when I restart it, the cookies that were supposed to be stored in CookieStore are not there. Here's what I've written:

public static void main( String[] args ) throws InterruptedException
{
    RequestConfig globalConfig = RequestConfig.custom()
            .setCookieSpec(CookieSpecs.STANDARD).build();
    BasicCookieStore cookieStore = new BasicCookieStore();
    HttpClientContext context = HttpClientContext.create();
    context.setCookieStore(cookieStore);
    CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
            .setDefaultRequestConfig(globalConfig)
            .setDefaultCookieStore(cookieStore)
            .build();
    httpclient.start();
    login(httpclient, context);
}

public static void login(CloseableHttpAsyncClient httpClient, HttpClientContext context) throws InterruptedException
{
    JSONObject json = new JSONObject("{ email : blahblahblah1, password : blahblahblah2 }");
    StringEntity requestEntity = new StringEntity(
            json.toString(),
            ContentType.APPLICATION_JSON);

    HttpPost postMethod = new HttpPost("http://localhost:8080/login");
    postMethod.setEntity(requestEntity);

    final CountDownLatch latch = new CountDownLatch(1);
    httpClient.execute(postMethod, context, new FutureCallback<HttpResponse>() {

        public void completed(final HttpResponse response) {
            latch.countDown();
            System.out.println(postMethod.getRequestLine() + "->" + response.getStatusLine());
            //System.out.println(context.getCookieStore().getCookies().size());
        }

        public void failed(final Exception ex) {
            latch.countDown();
            System.out.println(postMethod.getRequestLine() + "->" + ex);
        }

        public void cancelled() {
            latch.countDown();
            System.out.println(postMethod.getRequestLine() + " cancelled");
        }

    });
    latch.await();
}

I've read the HttpComponents documentation and the section 3.5 about cookies says:

HttpClient can work with any physical representation of a persistent cookie store that implements the CookieStore interface. The default CookieStore implementation called BasicCookieStore is a simple implementation backed by a java.util.ArrayList. Cookies stored in an BasicClientCookie object are lost when the container object get garbage collected. Users can provide more complex implementations if necessary

So I'm wondering if it's left to it's users to implement some kind of structure that can effectively store cookies or if I'm missing something.


Solution

  • Yes, using BasicCookieStore backed by ArrayList means that when your jvm exists, the data there is being lost just like any ArrayList in memory.

    BasicCookieStore class also implements Serializable so you can use that to persist it to disk and restore back on your app startup if the file was there.

    You can borrow some code from the tests verifying that flow TestBasicCookieStore#testSerialization.