Custom CookieManager

可以自定义CookieManager类的两个方面,即CookiePolicyCookieStore

CookiePolicy

为方便起见,CookiePolicy定义了以下用于接受 Cookie 的 预定义策略:

  • CookiePolicy.ACCEPT_ORIGINAL_SERVER仅接受来自原始服务器的 cookie。

  • CookiePolicy.ACCEPT_ALL接受所有 cookie。

  • CookiePolicy.ACCEPT_NONE不接受任何 cookie。

  • 您还可以通过实现CookiePolicyshouldAccept方法来定义自己的 cookie 策略。然后,您可以通过将此CookiePolicy传递给多参数CookieManager构造函数或调用setCookiePolicy(cookiePolicy)方法来更改现有的 cookie管理 器来使用它。

以下是 Cookie 策略的示例,该策略在应用CookiePolicy.ACCEPT_ORIGINAL_SERVER策略之前拒绝来自黑名单上的域的 Cookie:

import java.net.*;

public class BlacklistCookiePolicy implements CookiePolicy {
    String[] blacklist;

    public BlacklistCookiePolicy(String[] list) {
        blacklist = list;
    }

    public boolean shouldAccept(URI uri, HttpCookie cookie)  {
        String host;
        try {
            host =  InetAddress.getByName(uri.getHost()).getCanonicalHostName();
        } catch (UnknownHostException e) {
            host = uri.getHost();
        }

        for (int i = 0; i<blacklist.length; i++) {
	    if (HttpCookie.domainMatches(blacklist[i], host)) {
                return false;
            }
        }

        return CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(uri, cookie);
    }
}

创建BlacklistCookiePolicy实例时,将为它传递一个字符串 数组,这些字符串 表示您不希望接受 Cookie 的域。然后,将此BlacklistCookiePolicy实例设置为CookieManager的 Cookie 策略。例如:

String[] list = new String[]{ ".example.com" };
CookieManager cm = new CookieManager(null, new BlacklistCookiePolicy(list));
CookieHandler.setDefault(cm);

该示例代码将不接受来自主机的 cookie,例如:

host.example.com
domain.example.com

但是,此示例代码将接受来自主机的 Cookie,例如:

example.com
example.org
myhost.example.org

CookieStore

CookieStore是代表 Cookie 存储区域的interface。 CookieManager为每个 HTTP 响应将 cookie 添加到CookieStore,并为每个 HTTP 请求从CookieStore检索 cookie。

您可以实现此interface以提供自己的CookieStore,并在创建过程中将其传递给CookieManager。创建CookieManager实例后,无法设置CookieStore。但是,您可以通过调用CookieManager.getCookieStore()获得对 Cookie 存储的引用。这样做很有用,因为它使您能够利用 Java SE 提供的默认内存CookieStore实现并补充其功能。

例如,您可能想要创建一个永久性的 cookie 存储,该存储将保存 cookie,以便即使重新启动 Java 虚拟机也可以使用它们。您的实现将类似于以下内容:

  • 读取以前保存的所有 cookie。

  • 在运行时,将存储 cookie 并从内存中检索它们。

  • Cookies 在退出前会写到持久性存储中。

以下是此 Cookie 存储的不完整示例。本示例说明如何利用 Java SE 默认的内存 cookie 存储以及如何扩展其功能。

import java.net.*;
import java.util.*;

public class PersistentCookieStore implements CookieStore, Runnable {
    CookieStore store;

    public PersistentCookieStore() {
        // get the default in memory cookie store
        store = new CookieManager().getCookieStore();

        // todo: read in cookies from persistant storage
        // and add them store

        // add a shutdown hook to write out the in memory cookies
        Runtime.getRuntime().addShutdownHook(new Thread(this)); 
    }

    public void run() {
        // todo: write cookies in store to persistent storage
    }

    public void	add(URI uri, HttpCookie cookie) {
        store.add(uri, cookie);
    }

    public List<HttpCookie> get(URI uri) {
        return store.get(uri);
    }

    public List<HttpCookie> getCookies() {
        return store.getCookies();
    }
    
    public List<URI> getURIs() {
        return store.getURIs();
    }

    public boolean remove(URI uri, HttpCookie cookie) {
        return store.remove(uri, cookie);
    }

    public boolean removeAll()  {
        return store.removeAll();
    }
}