Cookie管理

はじめに

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

JDK 5.0より前のサポート

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の新機能

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を提供します。


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