CookieManager for multiple threads

2019-01-14 14:50发布

I am trying to make multiple connections via threads.

But every connection seems to override the other's cookies, resulting in the connections using the wrong cookies.

inside the threaded class's constructor:

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

Any way to manage the cookies per thread or per class?

New failed try:

Now every thread is using it's own index, yet they still seem to override each other cookie-wise. Any ideas?

public class threadedCookieStore implements CookieStore, Runnable {
    CookieStore[] store = new CookieStore[1000];
    int index;

    public threadedCookieStore(int new_index) {
        index = new_index;
        // get the default in memory cookie store
        store[index] = 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[index].add(uri, cookie);
    }

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

    public List<HttpCookie> getCookies() {
        return store[index].getCookies();
    }

    public List<URI> getURIs() {
        return store[index].getURIs();
    }

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

     public boolean removeAll()  {
         return store[index].removeAll();
    }
}

Within the class:

threadedCookieStore cookiestore = new threadedCookieStore(index);

manager = new CookieManager(cookiestore,CookiePolicy.ACCEPT_ALL);
manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(manager);

7条回答
Rolldiameter
2楼-- · 2019-01-14 15:18

Based on the answers in this thread, I created another very simple ThreadLocalCookieStore implementation and pushed it to GitHub (also providing it as a Maven dependency there):

public class ThreadLocalCookieStore implements CookieStore {
    private final static ThreadLocal<CookieStore> stores = new ThreadLocal<CookieStore>() {
        @Override protected synchronized CookieStore initialValue() { 
            return (new CookieManager()).getCookieStore(); //InMemoryCookieStore 
        }
    };

    @Override public void add(URI uri, HttpCookie cookie) { getStore().add(uri,cookie); }
    @Override public List<HttpCookie> get(URI uri) { return getStore().get(uri); }
    @Override public List<HttpCookie> getCookies() { return getStore().getCookies(); }
    @Override public List<URI> getURIs() { return getStore().getURIs(); }
    @Override public boolean remove(URI uri, HttpCookie cookie) { return getStore().remove(uri,cookie); }
    @Override public boolean removeAll() { return getStore().removeAll(); }
    @Override public int hashCode() { return getStore().hashCode(); }

    protected CookieStore getStore() { return stores.get(); }
    public void purgeStore() { stores.remove(); }
}

Without much code it becomes very simple to set the cookie store, with any policy value, e.g.:

CookieHandler.setDefault(new java.net.CookieManager(
    new ThreadLocalCookieStore(), CookiePolicy.ACCEPT_ALL));

In addition the dependency features a small sevlet @WebFilter, to separate cookie stores on multiple serlvet requests if required.

查看更多
登录 后发表回答