How to handle cookies in httpUrlConnection using cookieManager

Ok, the right way to do it is just like that:

Get Cookies from response header and load them into cookieManager:

static final String COOKIES_HEADER = "Set-Cookie";
HttpURLConnection connection = ... ;
static java.net.CookieManager msCookieManager = new java.net.CookieManager();

Map<String, List<String>> headerFields = connection.getHeaderFields();
List<String> cookiesHeader = headerFields.get(COOKIES_HEADER);

if (cookiesHeader != null) {
    for (String cookie : cookiesHeader) {
        msCookieManager.getCookieStore().add(null,HttpCookie.parse(cookie).get(0));
    }               
}

Get Cookies from cookieManager and load them into connection:

if (msCookieManager.getCookieStore().getCookies().size() > 0) {
    // While joining the Cookies, use ',' or ';' as needed. Most of the servers are using ';'
    connection.setRequestProperty("Cookie",
    TextUtils.join(";",  msCookieManager.getCookieStore().getCookies()));    
}

I've been searching/trying for days to fix my issue: cannot access protected web resources even after logging in successfully

I created the same app on iOS and didn't have the same problem because NSUrlConnection did the cookie maintenance for us behind the scene. On Android, I tried manually adding cookie

connection.setRequestProperty("Cookie", "PHPSESSID=str_from_server")

without any luck.

Finally I read this

and added the following 2 lines somewhere in the beginning of my app:

CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);

and everything works fine now.


@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.


The other answers are appropriate for their contexts, but nobody is saying the obvious: CookieHandler automatically deals with your cookies in most cases. To just maintain cookies from one request to the next -- for instance to maintain a server session -- then this line of code is sufficient:

CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

Make sure to run it once before your first request with UrlConnection.

Now I do zero cookie management myself, and all of my server session data is flawlessly maintained from request to request.

Am I crazy? Why is the internet silent on this? I can't even find it in the docs.