HttpURLConnectionを使用して複数のスレッドから同時にWebサイトに接続する必要がありましたが、接続ごとに異なるCookieを使用する必要がありました。 JavaはグローバルなCookieManagerの設定のみをサポートしているので、私は以下のハックを実装しました。HttpURLConnectionとJavaのCookieManagerを使用して接続ごとに異なるCookieを使用する方法
CookieHandler.setDefault(new CookieManager())
を呼び出す代わりに、CookieHandler
というカスタムを実装しました。これは、すべてのスレッドに対して異なるCookieStore
インスタンスを使用します。これは、リクエストごとにクリアされます。
私はsource codeのCookieManager
に基づいてSessionCookieManager
というクラスを作成しました。
メンバー変数cookieJar
が削除され、その使用法がgetCookieStore()
に置き換えられました。
次のコードが追加されました:すべての要求の後
CookieHandler.setDefault(SessionCookieManager.getInstance());
、現在のスレッドのCookieStore
がクリアされます。
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
として設定されています:
try {
...
} finally {
SessionCookieManager.getInstance().clear();
}
これは質問ですか?あなたがしたことをあなたが列挙しているように聞こえます。これが良いアイデアかどうか尋ねていますか?私はそうではないと思う。このコードはスレッドセーフではありません。ロックのみが、各スレッドが意図したCookieStoreだけを見ることを保証します。可能であれば、代わりにHttpClientを使用することをお勧めします。このようなコードレビューを投稿することを検討するかもしれません。http://codereview.stackexchange.com/ –
同意しましたが、なぜこのコードはスレッドセーフではないと思いますか? – nivs
私はそれを誤解しました。スレッドの問題はありません。私が見る唯一の否定は、あなたがSunの内部クラスを参照しなければならないということです。あなたはそれに問題がありますか? –