@David's answer is the best of the lot. Its easiest to maintain a local CookieManager and manually write into and read from the cookie store associated with this cookie manager.
This code loads the Cookies from a response into the cookie manager :
/**
* Gets Cookies from the response header and loads them into cookie manager
*
* @param conn instance of {@link HttpURLConnection} object
* @param cookieManager the cookie manager({@link CookieManager} instance) in which the cookies are to be loaded<p>In case a null object is passed, the function will not perform any action and return back to the caller. </p>
*/
public static void loadResponseCookies(@Nullable HttpURLConnection conn,@Nullable CookieManager cookieManager) {
//do nothing in case a null cokkie manager object is passed
if (cookieManager == null || conn == null){
return;
}
List<String> cookiesHeader = conn.getHeaderFields().get(COOKIES_HEADER);
if (cookiesHeader != null) {
for (String cookieHeader : cookiesHeader) {
List<HttpCookie> cookies;
try {
cookies = HttpCookie.parse(cookieHeader);
} catch (NullPointerException e) {
log.warn(MessageFormat.format("{0} -- Null header for the cookie : {1}",conn.getURL().toString(), cookieHeader.toString()));
//ignore the Null cookie header and proceed to the next cookie header
continue;
}
if (cookies != null) {
Debug("{0} -- Reading Cookies from the response :", conn.getURL().toString());
for (HttpCookie cookie : cookies) {
Debug(cookie.toString());
}
if (cookies.size() > 0) {
cookieManager.getCookieStore().add(null, HttpCookie.parse(cookieHeader).get(0));
}
}
}
}
}
This code populates the HttpUrlConnection object with the cookies associated with the cookie manager :
public void populateCookieHeaders(HttpURLConnection conn) {
if (this.cookieManager != null) {
//getting cookies(if any) and manually adding them to the request header
List<HttpCookie> cookies = this.cookieManager.getCookieStore().getCookies();
if (cookies != null) {
if (cookies.size() > 0) {
Debug("{0} -- Adding Cookie Headers : ", url.toString());
for (HttpCookie cookie : cookies) {
Debug(cookie.toString(), null);
}
//adding the cookie header
conn.setRequestProperty(COOKIE_REQUEST_HEADER, StringUtils.join(cookies, ";"));
}
}
}
}
This is the most thread safe way to handle cookies.
I tried using a threadlocal cookiestore and an extension of CookieManager. Neither of these approaches worked in my case.