HttpURLConnection with a non system-wide CookieHandler

845 views Asked by At

I have a web application that makes HTTP requests using HttpURLConnection. I need it to handle cookies. I know that it's easily done by adding just one line of code, something like

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

The problem is this way I'm setting the system-wide cookie handler as the documentation describes. This also affects other web applications that run in the same servlet container. For example if I want CookiePolicy.ACCEPT_ORIGINAL_SERVER in one application and CookiePolicy.ACCEPT_ALL in another, it won't work.

Is there a way to have a CookieHandler that is only used by a single HttpURLConnection instance?

1

There are 1 answers

4
fhofmann On BEST ANSWER

In standard oracle implementation the HttpURLConnection get the default CookieHandler on the constructor, so this is one possible solution. Create a synchronized singleton factory that create the HttpURLConnections using a specific manager for each application. Not good idea in my opinion.

Other bad idea is provide your own CookiePolicy and do the trick on the shouldAccept method.

Or you can manually control cookies on the app that should not share the CookieHandler:

        HttpURLConnection firstCall = (HttpURLConnection) new URL("http://www.google.com").openConnection();
        firstCall.connect();
        List<HttpCookie> cookieList = HttpCookie.parse(firstCall.getHeaderField("Set-Cookie"));
        firstCall.disconnect();
        StringBuilder cookies = new StringBuilder();
        for(HttpCookie cookie:cookieList) {
            //if(cookie.SOME_VALIDATION) {
                if(cookies.length() > 0) {
                    cookies.append("; ");
                }
                cookies.append(cookie.toString());
            //}
        }
        HttpURLConnection secondCall = (HttpURLConnection) new URL("http://www.google.com").openConnection();
        secondCall.setRequestProperty("Cookie", cookies.toString());
        secondCall.connect();
        //dosomething
        secondCall.disconnect();