Как использовать разные файлы cookie для каждого подключения с помощью HttpURLConnection и CookieManager в Java

Мне нужно было подключиться к веб-сайту из нескольких потоков одновременно, используя HttpURLConnection, но использовать разные файлы cookie для каждого подключения. Поскольку Java поддерживает только установку глобального CookieManager, я реализовал следующий прием.

Вместо вызова CookieHandler.setDefault(new CookieManager()) я реализовал собственный CookieHandler, который использует разные экземпляры CookieStore для каждого потока, который очищается после каждого запроса.

Я создал класс под названием SessionCookieManager на основе исходный код CookieManager.

Переменная-член cookieJar была удалена, а ее использование было заменено на getCookieStore().

Был добавлен следующий код:

public class SessionCookieManager extends CookieHandler {
    private final static SessionCookieManager ms_instance = new SessionCookieManager();

    public static SessionCookieManager getInstance() {
        return ms_instance;
    }

    private final static ThreadLocal<CookieStore> ms_cookieJars = new ThreadLocal<CookieStore>() {
        @Override
        protected synchronized CookieStore initialValue() { return new sun.net.www.protocol.http.InMemoryCookieStore(); }
    };

    public void clear() {
        getCookieStore().removeAll();
    }

    public CookieStore getCookieStore() {
        return ms_cookieJars.get();
    }

Перед первым запросом пользовательский CookieManager устанавливается в качестве глобального значения по умолчанию CookieHandler:

CookieHandler.setDefault(SessionCookieManager.getInstance());

После каждого запроса CookieStore текущего потока очищается:

try {
    ...
} finally {
    SessionCookieManager.getInstance().clear();
}

person nivs    schedule 10.06.2012    source источник
comment
Это вопрос? Похоже, вы перечисляете то, что сделали. Вы спрашиваете, хорошая ли это идея? Я думаю, что это не так. Этот код не является потокобезопасным. Только блокировка гарантирует, что каждый поток видит только предполагаемый CookieStore. Я рекомендую вместо этого использовать HttpClient, если вы можете. Вы можете опубликовать подобный обзор кода здесь codereview.stackexchange.com   -  person John Watts    schedule 10.06.2012
comment
Согласен, но почему вы думаете, что этот код не является потокобезопасным?   -  person nivs    schedule 11.06.2012
comment
Я неправильно это понял. Я не вижу проблем с потоками. Единственный минус, который я вижу, - это то, что вам пришлось ссылаться на внутренний класс Sun. У вас с этим проблемы?   -  person John Watts    schedule 12.06.2012
comment
Я создал полное руководство на основе этого @ stackoverflow.com/questions/16305486 /   -  person Wurstbro    schedule 04.05.2013


Ответы (1)


Один из способов решения проблемы - напрямую использовать заголовок Cookie вместо отправки файла cookie. См. Заголовок файла cookie здесь: https://msdn.microsoft.com/en-us/library/windows/desktop/aa384321(v=vs.85).aspx, который можно изменять при каждом вызове.

Cookie: <name>=<value> [;<name>=<value>]...
person Dheerendra Kulkarni    schedule 19.11.2015