FileDocCategorySizeDatePackage
CookieManager.javaAPI DocJava SE 6 API11329Tue Jun 10 00:25:40 BST 2008java.net

CookieManager

public class CookieManager extends CookieHandler
CookieManager provides a concrete implementation of {@link CookieHandler}, which separates the storage of cookies from the policy surrounding accepting and rejecting cookies. A CookieManager is initialized with a {@link CookieStore} which manages storage, and a {@link CookiePolicy} object, which makes policy decisions on cookie acceptance/rejection.

The HTTP cookie management in java.net package looks like:

use
CookieHandler <------- HttpURLConnection
^
| impl
| use
CookieManager -------> CookiePolicy
| use
|--------> HttpCookie
| ^
| | use
| use |
|--------> CookieStore
^
| impl
|
Internal in-memory implementation
  • CookieHandler is at the core of cookie management. User can call CookieHandler.setDefault to set a concrete CookieHanlder implementation to be used.
  • CookiePolicy.shouldAccept will be called by CookieManager.put to see whether or not one cookie should be accepted and put into cookie store. User can use any of three pre-defined CookiePolicy, namely ACCEPT_ALL, ACCEPT_NONE and ACCEPT_ORIGINAL_SERVER, or user can define his own CookiePolicy implementation and tell CookieManager to use it.
  • CookieStore is the place where any accepted HTTP cookie is stored in. If not specified when created, a CookieManager instance will use an internal in-memory implementation. Or user can implements one and tell CookieManager to use it.
  • Currently, only CookieStore.add(URI, HttpCookie) and CookieStore.get(URI) are used by CookieManager. Others are for completeness and might be needed by a more sophisticated CookieStore implementation, e.g. a NetscapeCookieSotre.

There're various ways user can hook up his own HTTP cookie management behavior, e.g.

  • Use CookieHandler.setDefault to set a brand new {@link CookieHandler} implementation
  • Let CookieManager be the default {@link CookieHandler} implementation, but implement user's own {@link CookieStore} and {@link CookiePolicy} and tell default CookieManager to use them:
    // this should be done at the beginning of an HTTP session
    CookieHandler.setDefault(new CookieManager(new MyCookieStore(), new MyCookiePolicy()));
    
  • Let CookieManager be the default {@link CookieHandler} implementation, but use customized {@link CookiePolicy}:
    // this should be done at the beginning of an HTTP session
    CookieHandler.setDefault(new CookieManager());
    // this can be done at any point of an HTTP session
    ((CookieManager)CookieHandler.getDefault()).setCookiePolicy(new MyCookiePolicy());
    

The implementation conforms to RFC 2965, section 3.3.

version
%I%, %E%
author
Edward Wang
since
1.6

Fields Summary
private CookiePolicy
policyCallback
private CookieStore
cookieJar
Constructors Summary
public CookieManager()
Create a new cookie manager.

This constructor will create new cookie manager with default cookie store and accept policy. The effect is same as CookieManager(null, null).



    /* ---------------- Ctors -------------- */
    
                                   
      
        this(null, null);
    
public CookieManager(CookieStore store, CookiePolicy cookiePolicy)
Create a new cookie manager with specified cookie store and cookie policy.

param
store a CookieStore to be used by cookie manager. if null, cookie manager will use a default one, which is an in-memory CookieStore implmentation.
param
cookiePolicy a CookiePolicy instance to be used by cookie manager as policy callback. if null, ACCEPT_ORIGINAL_SERVER will be used.

        // use default cookie policy if not specify one
        policyCallback = (cookiePolicy == null) ? CookiePolicy.ACCEPT_ORIGINAL_SERVER
                                                : cookiePolicy;
        
        // if not specify CookieStore to use, use default one
        if (store == null) {
            cookieJar = new sun.net.www.protocol.http.InMemoryCookieStore();
        } else {
            cookieJar = store;
        }
    
Methods Summary
public java.util.Mapget(java.net.URI uri, java.util.Map requestHeaders)

        // pre-condition check
        if (uri == null || requestHeaders == null) {
            throw new IllegalArgumentException("Argument is null");
        }
        
        Map<String, List<String>> cookieMap =
                        new java.util.HashMap<String, List<String>>();
        // if there's no default CookieStore, no way for us to get any cookie
        if (cookieJar == null)
            return Collections.unmodifiableMap(cookieMap);
        
        List<HttpCookie> cookies = new java.util.ArrayList<HttpCookie>();
        for (HttpCookie cookie : cookieJar.get(uri)) {
            // apply path-matches rule (RFC 2965 sec. 3.3.4)
            if (pathMatches(uri.getPath(), cookie.getPath())) {
                cookies.add(cookie);
            }
        }
        
        // apply sort rule (RFC 2965 sec. 3.3.4)
        List<String> cookieHeader = sortByPath(cookies);
        
        cookieMap.put("Cookie", cookieHeader);
        return Collections.unmodifiableMap(cookieMap);
    
public java.net.CookieStoregetCookieStore()
To retrieve current cookie store.

return
the cookie store currently used by cookie manager.

        return cookieJar;
    
private booleanpathMatches(java.lang.String path, java.lang.String pathToMatchWith)

        if (path == pathToMatchWith)
            return true;
        if (path == null || pathToMatchWith == null)
            return false;
        if (path.startsWith(pathToMatchWith))
            return true;
        
        return false;
    
public voidput(java.net.URI uri, java.util.Map responseHeaders)

        // pre-condition check
        if (uri == null || responseHeaders == null) {
            throw new IllegalArgumentException("Argument is null");
        }
        
        
        // if there's no default CookieStore, no need to remember any cookie
        if (cookieJar == null)
            return;
        
        for (String headerKey : responseHeaders.keySet()) {
            // RFC 2965 3.2.2, key must be 'Set-Cookie2'
            // we also accept 'Set-Cookie' here for backward compatibility
            if (headerKey == null
                || !(headerKey.equalsIgnoreCase("Set-Cookie2")
                     || headerKey.equalsIgnoreCase("Set-Cookie")
                    )
                )
            {
                continue;
            }
            
            for (String headerValue : responseHeaders.get(headerKey)) {
                try {
                    List<HttpCookie> cookies = HttpCookie.parse(headerValue);
                    for (HttpCookie cookie : cookies) {
                        if (shouldAcceptInternal(uri, cookie)) {
                            cookieJar.add(uri, cookie);
                        }
                    }
                } catch (IllegalArgumentException e) {
                    // invalid set-cookie header string
                    // no-op
                }
            }
        }
    
public voidsetCookiePolicy(java.net.CookiePolicy cookiePolicy)
To set the cookie policy of this cookie manager.

A instance of CookieManager will have cookie policy ACCEPT_ORIGINAL_SERVER by default. Users always can call this method to set another cookie policy.

param
cookiePolicy the cookie policy. Can be null, which has no effects on current cookie policy.

        if (cookiePolicy != null) policyCallback = cookiePolicy;
    
private booleanshouldAcceptInternal(java.net.URI uri, java.net.HttpCookie cookie)

        try {
            return policyCallback.shouldAccept(uri, cookie);
        } catch (Exception ignored) { // pretect against malicious callback
            return false;
        }
    
private java.util.ListsortByPath(java.util.List cookies)

        Collections.sort(cookies, new CookiePathComparator());

        List<String> cookieHeader = new java.util.ArrayList<String>();
        for (HttpCookie cookie : cookies) {
            // Netscape cookie spec and RFC 2965 have different format of Cookie
            // header; RFC 2965 requires a leading $Version="1" string while Netscape
            // does not.
            // The workaround here is to add a $Version="1" string in advance
            if (cookies.indexOf(cookie) == 0 && cookie.getVersion() > 0) {
                cookieHeader.add("$Version=\"1\"");
            }

            cookieHeader.add(cookie.toString());
        }
        return cookieHeader;