X

Cookie Handling in Java SE 6

Guest Author

by John Zukowski

Back in September 2005, the Cookie Management with CookieHandler tip described the J2SE 5.0 support for managing cookies over network connections.
The 5.0 release provided the framework for dealing with these little nuggets of
information, but the task of doing all the work was left to you, the developer.
You only had to follow the defined API, but there was much work that needed to
be done to actually get cookie management going well for your programs.

A quick look back to the J2SE 5.0 API brings you right to the abstract
CookieHandler class but with no real implementation, no storage mechanism, no storage policy, and nothing to store. Jump ahead to Java SE 6, and the
CookieManager class offers just such an implementation of CookieHandler. CookieStore is the storage mechanism, and CookiePolicy offers a policy for accepting or rejecting cookies. Lastly, HttpCookie is the object to store.

What used to be a difficult though doable task in J2SE 5.0, becomes simple
construction of existing classes in Java SE 6.

Here's the working J2SE 5.0 program for working with cookies:

import java.io.\*;
import java.net.\*;
import java.util.\*;
public class Fetch {
public static void main(String args[]) throws Exception {
if (args.length == 0) {
System.err.println("URL missing");
System.exit(-1);
}
String urlString = args[0];
CookieHandler.setDefault(new ListCookieHandler());
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
Object obj = connection.getContent();
url = new URL(urlString);
connection = url.openConnection();
obj = connection.getContent();
}
}

Notice the setDefault method call to CookieHandler in the middle. The ListCookieHandler class was the tip's implementation of a basic CookieHandler.

The Java SE 6 version of the same program is nearly identical but has just
one change to the following line:

CookieHandler.setDefault(new CookieManager());

You don't need to provide any additional code. It is really that simple to go
between the different APIs. There are some other differences, but changing the
one line in the Fetch program has the second network connection use the cookies returned from the first.

Now for the differences. Java SE 6 has a CookiePolicy which offers the CookieManager the ability to accept all cookies, accept no cookies, or only accept cookies from the original host. To setup the CookieManager with a different policy, you use one of the constants in the CookiePolicy interface: ACCEPT_ALL, ACCEPT_NONE, or ACCEPT_ORIGINAL_SERVER. The last option is the
default when none is set. To configure the cookie manager, just call its
setCookiePolicy method with the appropriate constant as shown here:

CookieManager manager = new CookieManager();
manager.setCookiePolicy(CookiePolicy.ACCEPT_NONE);
CookieHandler.setDefault(manager);

In addition, you can call the second constructor for CookieManager that accepts both a CookieStore and CookiePolicy argument:

CookieManager(CookieStore store, CookiePolicy cookiePolicy)

Passing in a null store will have the system use the predefined in-memory
version. You can also define your own implementation of the interface if you
wish to offer longer term storage of cookies.

Before showing the corrected version of the Fetch program, there is one more API difference to mention: how to get the list of cookies from the cookie jar,
err..., manager. The CookieManager class has a getCookieStore method to get the CookieStore. You then ask the store for its List of cookies with the getCookies method, and can loop through the list.

Here's a modified version of the earlier program that utilizes the Java SE 6
version of the cookie handling API. While the basic program hasn't changed
much, the need for all the supporting custom classes is now no longer necessary.

import java.io.\*;
import java.net.\*;
import java.util.\*;
public class Fetch {
public static void main(String args[]) throws Exception {
Console console = System.console();
if (args.length == 0) {
System.err.println("URL missing");
System.exit(-1);
}
String urlString = args[0];
CookieManager manager = new CookieManager();
manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(manager);
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
Object obj = connection.getContent();
url = new URL(urlString);
connection = url.openConnection();
obj = connection.getContent();
CookieStore cookieJar = manager.getCookieStore();
List cookies = cookieJar.getCookies();
for (HttpCookie cookie: cookies) {
console.printf("Cookie: %s%n", cookie);
}
}
}

Just compile and run the program to see if visiting a particular URL will
leave a cookie on your system. If you don't enable ACCEPT_ALL, visiting
http://www.sun.com will not show any cookies, but enabling all will show three. Your run will produce different results.

> java Fetch http://www.sun.com
Cookie: JROUTE=9999
Cookie: JSESSIONID=999999995d3f13ffffffffc68433979b7f5b0
Cookie: Starload=star-fep7

Yes, going from the J2SE 5.0 cookie handling mechanism to Java SE 6 is that
easy. You don't have to implement even one additional interface if the default
functionality is sufficient. For a refresher on the difficulties involved in
creating the J2SE 5.0 version of the handler, be sure to revisit the earlier
tip
.

Be sure to try out the Tech Tips Quiz, found later in that same issue.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.