HTTP状態管理メカニズムは、HTTPの要求と応答を使ってステートフル・セッションを作成する方法を指定します。仕様については、「RFC 2965: HTTP State Management Mechanism」(http://www.ietf.org/rfc/rfc2965.txt?number=2965)を参照してください。
JDK 5.0より前では、Cookie管理をアプリケーションに追加することが可能でした。ただし、APIのサポートはやや不十分で、Cookie管理につながる点はまったくありませんでした。各アプリケーションでは、java.net.URLConnectionクラスから次の2つのメソッドを使用して、各HTTP要求/応答のCookieを個別に処理する必要がありました。
setRequestProperty()
getHeaderFields()
1つ目のメソッドは、HTTP要求の送信前に呼び出す必要があります。これは、HTTPヘッダーの現在のURLに適したCookieを設定するためです。2つ目のメソッドは、HTTPサーバーにより送信された応答ヘッダーからCookieを取得するために使用します。
この方法でCookieサポートを追加することは可能ですが、コードが断片化されることになります。これはエラーが発生しやすく、保守が大変です。
JDK 5.0では、HTTP状態管理ポリシーの実装をHTTPプロトコル・ハンドラに組み込むために、abstractクラスを使用した新しいコールバック・メカニズムを導入しました。アプリケーションやWebコンテナでは、新しいAPIの具象サブクラスを用意すればCookie管理の導入が可能です。
この新しいabstractクラスはjava.net.CookieHandlerと呼ばれます。これには、JVM用に現在のCookieHandlerの登録や取得を行うメカニズムに加えて、特定URIに対応するCookieの取得や記録を行うためのメソッドが用意されています。
CookieHandlerには、getDefault()およびsetDefault()の2つのstaticメソッドが含まれています。これは、VMにおいてデフォルトのCookieHandlerの取得や登録を行うためのものです。さらに、Cookieリストを返すための2つのインスタンス・メソッド、get()とput()は、URLをベースとし、それぞれ応答ヘッダーからCookieリストを保存します。
Cookieは、Map<String,List<String>>として表されます。つまり、Cookieのヘッダー・フィールド名から、Stringによって表される一連のリストまでのMapです。これまでに定義された「Set-Cookie2」と「Cookie」の2つの状態管理ヘッダーが用意されています。前者は応答ヘッダーでCookieを返す場合に使用し、後者はHTTP要求ヘッダーでCookieの設定を行う場合に使用します。
RFC2965からの例を次に示します。
1. ユーザー・エージェント ->サーバー
POST /acme/login HTTP/1.1
[form data]
2. サーバー ->ユーザー・エージェント
HTTP/1.1 200 OK
Set-Cookie2:Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
3. ユーザー・エージェント ->サーバー
POST /acme/pickitem HTTP/1.1
Cookie:$Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"
[form data]
次に、CookieHandler実装の簡単な例を示します。基本的に2つのメソッドが用意されています。これらのメソッドでは、所定の要求URIと要求ヘッダー(Cookieヘッダーを除く)を実装し、Cookieキャッシュから関連するCookieをすべて取得し、要求URIと要求ヘッダーが与えられたCookieキャッシュに対して適切なCookieを記録します。
class MyCookieHandler extends CookieHandler { public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders) throws IOException { // the cookies will be included in request Map<String, List<String>> map = new HashMap<String, List<String>>(); List<String> l = retrieveCookies(uri, rqstHdrs); map.put("Cookie",l); return Collections.unmodifiableMap(map); } public void put(URI uri, Map responseHeaders) throws IOException { // check response has cookies[1] List l = (List)responseHeaders.get("Set-Cookie2"); if (l != null) { // save the cookies in a cookie cache storeCookies(uri, l); } } }
retrieveCookies()
とstoreCookies()
の各メソッドは、この例では省略されているバックエンドのCookie管理機能と対話するための「マジック」機能です。
この機能がVMに登録されると、HTTPトランザクションを発行する時点で有効になります。
public static void main(String args[]) throws Exception { ...... CookieHandler.setDefault(new MyCookieHandler()); HttpURLConnection http = (HttpURLConnection)url.openConnection(); int respCode = http.getResponseCode(); http.disconnect(); ...... }
これには、Cookieマネージャのデフォルトの実装が存在しません 。しかし、この点は将来変更される可能性があります。Java Plug-inとJava WebStartでは、それぞれの環境においてデフォルトのCookieHandlerを提供します。