« どうしてJaveでCookieが取得できないんだろう?(4) | トップページ | Javaでサーモグラフィーの色のグラデーションを再現(6) »

2010年9月26日 (日)

どうしてJaveでCookieが取得できないんだろう?(5)

前回 からの続きです。

 前回はJavaでログインサイトからのセッションIDを取得する際に、クッキーが取得できないという問題について述べました。これは各ログインサイトが行っている複数の古いクッキーの上書き処理が、Java側のクッキー適用順の違いによって新しいクッキーまで消してしまっているためで、これによりセッションIDを含んだクッキーを取得できませんでした。

今回はこの問題について再度、発生する条件をまとめ、対策について触れていきます。

 さて、前回の「クッキー適用順の怪」問題でしたが、まずは”Set-Cookie”ヘッダについて、”Set-Cookie”ヘッダはHTTPヘッダに複数含めることができます。しかしながら、複数存在する”Set-Cookie”ヘッダをどの順番で適用するかの条件は調べても見当たりませんでした。

Javaでは、この複数のSet-Cookieヘッダの文字列を取得すると、なぜか、先頭と後尾が順序逆転したリストで得られます。そのため、複数のクッキーヘッダを上から順番に処理し、上書きするということを暗黙的に期待して構築されているWebサイトでは、問題が起こる可能性があります。

 いくらSet-Cookieヘッダはどの順番で適用するか決まってないと言ったとしても、ここはJavaのクッキーヘッダの適用順序が一般的でないことが問題なのでしょう。

・対策

 ということで、Javaで正常にSet-Cookieヘッダをクッキーとして取得できるように簡単な修正を施します。修正を施すのは、CookieManagerです。このCookieManagerを修正することで、順序が逆転しているクッキーヘッダを正しい順序で処理するように変更します。

 ここでの注意としましては、クッキーヘッダの順序が逆転しているからといってそれを単純に逆転し直すということはしません。なぜか? それはこの問題は今後Javaのアップデートによって修正される可能性があるからです。目標としては、クッキーヘッダの順序の取り扱いが正しくなったとしても動作するように実装します。単にJavaのバージョンによる依存を残したくないからなんですが。

「CorrectedCookieManager.java」をダウンロード

 このクラスはCookieManagerを継承しており、クッキーを格納する際に呼び出されるpublic void put(URI uri, Map<String, List<String>> responseHeader)をオーバーライドしています。

 内部ではSet-Cookieヘッダのリストを、expireの日付順にソートし直し、古いものが先頭にくるようにしています。なお、取得できるヘッダのリストやマップは変更不可なので、それぞれコピーを作成してからソートし、その後スーパークラスであるCookieManagerへ丸投げしています。

 またこのクラスには、第一のexpire解析失敗バグについても対策が施されています。まずpublic static boolean isParsable() というメソッドが定義されており、クッキーのexpire解析のテストを行えます。もしも正しく解析できない場合には、実際のクッキー解析の際にLocation.setDefault(Locale.US)を実行したり、元のロケールに戻したりということを行います。

 実際の使い方ですが、

CorrectedCookieManager manager = new CorrectedCookieManager();
CookieHandler.setDefault(manager);

 これで、以降のHttpURLConnectionでのクッキー処理は正しく行われます。ほとんどの機能はCookieManagerに準じていますし、変更も30行程度の追加だけなので、誰でも簡単に実装できると思います。

 ちなみにCorrectedCookieManager.javaにはデモプログラムとしてmainメソッドが記述されていますので、CookieManagerとして使う以外にも、自身のJVMのクッキー処理の様子などを見ることができます。よかったら実行して見てください。エンコーディングはUTF-8です。

 これでやっとJavaの基本の処理機構をを用いてのWebプログラミングの準備が整ったと言えます。これで「どうしてJavaでCookieが取得できないんだろう?」を終えて、次はJavaで作るシンプルなHTTPclient編に挑戦したいと思います。それでは。

« どうしてJaveでCookieが取得できないんだろう?(4) | トップページ | Javaでサーモグラフィーの色のグラデーションを再現(6) »

Java」カテゴリの記事

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: どうしてJaveでCookieが取得できないんだろう?(5):

« どうしてJaveでCookieが取得できないんだろう?(4) | トップページ | Javaでサーモグラフィーの色のグラデーションを再現(6) »