Cookie 管理

はじめに

HTTP 状態管理メカニズムは、HTTP の要求と応答を使ってステートフルセッションを作成する方法を指定します。仕様については、「RFC 2965: HTTP State Management Mechanism」(http://www.ietf.org/rfc/rfc2965.txt?number=2965) を参照してください。

Tiger 以前のサポート

Tiger 以前、Cookie 管理をアプリケーションに追加することは可能でした。ただし、API のサポートはやや不十分で、Cookie 管理につながる点はまったくありませんでした。各アプリケーションでは、java.net.URLConnection クラスから次の 2 つのメソッドを使用して、各 HTTP 要求/応答の Cookie を個別に処理する必要がありました。

setRequestProperty()
getHeaderFields()

1 つ目のメソッドは、HTTP 要求の送信前に呼び出す必要があります。これは、HTTP ヘッダーの現在の URL に適した Cookie を設定するためです。2 つ目のメソッドは、HTTP サーバーにより送信された応答ヘッダーから Cookie を取得するために使用します。

この方法で Cookie サポートを追加することは可能ですが、コードが断片化されることになります。これはエラーが発生しやすく、保守が大変です。

Tiger の新機能

abstract クラスを使用した新しいコールバックメカニズムを導入しました。これは、HTTP 状態管理ポリシーの実装を HTTP プロトコルハンドラに接続することを目的としたものです。アプリケーションや 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();
        ......
}

J2SE には、Cookie マネージャーのデフォルトの実装が存在しません。しかし、この点は将来変更される可能性があります。Java Plug-in と Java WebStart では、それぞれの環境においてデフォルトの CookieHandler を提供します。


Copyright © 1993, 2013, Oracle and/or its affiliates. All rights reserved.