Thursday April 09, 2009 | Jean-Christophe Collet's Weblog Jean-Christophe Collet's Weblog |
|
As I mentioned in my previous post, JDK 6 introduced an extended cookie management API. The main class being java.net.CookieManager which extends the abstract class java.net.CookieHandler. It is supplemented by java.net.HttpCookie, java.net.CookieStore and java.net.CookiePolicy. Its main purpose is to provide a complete and easy to use cookie handler. By default, for backward compatibility reasons, it is not set as the default CookieHandler but this tutorial provides a quick overview of its simplest usage: With a simple in-memory store (i.e. cookies are not kept beyond the session) and a simple policy (only accept cookies if its domain matches the one of the originating site). What if you would like to keep the cookies between sessions or/and have a smarter filtering (with a white-list for instance)? Well, you don't need to write your own CookieHandler for that, all you need to do is to provide your own implementations of the CookiePolicy and/or of the CookieStore. Implementing the CookiePolicy is really simple as all that is required is one method: public boolean shouldAccept(URI uri, HttpCookie cookie); Just have it return true if you want to accept the cookie. That's where you'd check your white-list/black-list for instance. CookieStore is a bit more complex. There are 6 methods to implement: public void add(URI uri, HttpCookie cookie); public List<HttpCookie> get(URI uri); public List<HttpCookie> getCookies(); public List<URI> getURIs(); public boolean remove(URI uri, HttpCookie cookie); public boolean removeAll(); I won't go into the details (see the javadoc for that) but most of them are pretty much self explicit and straightforward to implement. The only method worth mentioning is the second one on that list, get(), because when implementing it you are expected to enforce some rules, like not returning a cookie flagged "secure" if the URI's protocol isn't "https", or expired cookies. If you're planning on implementing your own store, I'd recommend studying the code of the in-memory one we provide as part of the openJDK. The class is called sun.net.www.protocol.http.InMemoryCookieStore and therefore can be found in jdk/src/share/classes/sun/net/www/protocol/http. Now that you have your own policy and/or store, all you need to do to make use of them is: CookieHandler.setDefault(new CookieManager(myStore, myPolicy)); Because of this flexibility, the provided CookieManager should cover most needs. Only very advanced cases would require writing your own CookieHandler. One that comes to mind would be when more than one store is used, one for long persistent cookies and one for session-limited cookies, with the matching policies. I hope you found this helpful. HTTP Cookie support was introduced in JDK 5 with the CookieHandler API, then significantly extended in JDK 6 with HttpCookie, CookieManager, CookiePolicy and CookieStore. However a number of bugs (many due to the fact that the implementation followed the RFCs specs more closely than your average browser or server) and missing features made it less than perfect and somewhat of a pain to work with what is really out "there". The good news is that these have been fixed in JDK 7 and I wanted to take some time to outline some of these. First and foremost, CR 6644726 was a bucket for quite a few (7 to be exact) of these, including some domain matching problems. Also noticeable is CR 6641309 which deals with the separator used when sending multiple cookies in one header. CR 6641315 was about parsing expiration dates for Netscape style cookies. And CR 6790677 pointed out that unknown cookie attributes should be ignored instead of generating an error, while CR 6692802 added support for the HttpOnly attribute. Finally CR 6791927 complained about Locale issue when parsing expiration dates. Now that all these bugs have been fixed, I have been able to test the Cookie API with various sites making heavy use of cookies (Google mail, Google maps, Yahoo, Amazon, etc...), so I'm confident we do have a reasonably functional cookie API in JDK 7. In (near) future posts, I will give some code examples of its uses and go over some of tips and tricks. Don't forget JavaOne is June 2nd - June 5th! |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||