I needed to connect to a website from multiple threads simultaneously using HttpURLConnection, but use different cookies for each connection. Since Java only supports setting a global CookieManager, I've implemented the following hack.
Instead of calling CookieHandler.setDefault(new CookieManager())
, I've implemented a custom CookieHandler
which uses a different CookieStore
instance for every thread, which is cleared after each request.
I've created class called SessionCookieManager
based on the source code of CookieManager
.
The cookieJar
member variable was removed, and its usage has been replaced by getCookieStore()
.
The following code was added:
public class SessionCookieManager extends CookieHandler {
private final static SessionCookieManager ms_instance = new SessionCookieManager();
public static SessionCookieManager getInstance() {
return ms_instance;
}
private final static ThreadLocal<CookieStore> ms_cookieJars = new ThreadLocal<CookieStore>() {
@Override
protected synchronized CookieStore initialValue() { return new sun.net.www.protocol.http.InMemoryCookieStore(); }
};
public void clear() {
getCookieStore().removeAll();
}
public CookieStore getCookieStore() {
return ms_cookieJars.get();
}
Before the first request, the custom CookieManager
is set as the global default CookieHandler
:
CookieHandler.setDefault(SessionCookieManager.getInstance());
After every request, the current thread's CookieStore
is cleared:
try {
...
} finally {
SessionCookieManager.getInstance().clear();
}
One work around would be to use Cookie header directly instead sending the cookie. See cookie header here: https://msdn.microsoft.com/en-us/library/windows/desktop/aa384321(v=vs.85).aspx which you can change every call.