Мне нужно было подключиться к веб-сайту из нескольких потоков одновременно, используя 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();
}