JavaにおけるHTTPクッキーの手引き

JavaでのHTTP Cookieのガイド

1. 概要

この記事では、Javaネットワークプログラミングを使用した低レベルの操作について説明します。 Cookieについて詳しく見ていきます。

Javaプラットフォームには、java.netパッケージにバンドルされた組み込みのネットワークサポートが付属しています。

import java.net.*;

2. HTTP Cookie

クライアントがHTTP要求をサーバーに送信し、その応答を受信するたびに、サーバーはこのクライアントを忘れます。 次回クライアントが再度要求するとき、それはまったく新しいクライアントと見なされます。

ただし、私たちが知っているように、Cookieを使用すると、サーバーが複数の要求と応答のペアでクライアントを記憶できるように、クライアントとサーバーの間にセッションを確立できます。

以降、このセクションから、Cookieを使用してJavaネットワークプログラミングでのクライアント/サーバー通信を強化する方法を学習します。

Cookieを処理するためのjava.netパッケージのメインクラスはCookieHandlerです。 CookieManagerCookiePolicyCookieStoreHttpCookieなどの他のヘルパークラスとインターフェイスがあります。

3. CookieHandlerクラス

このシナリオを考えてみましょう。 http://example.comでサーバー、またはHTTPプロトコルを使用するその他のURLと通信している場合、URLオブジェクトはHTTPプロトコルハンドラーと呼ばれるエンジンを使用します。

このHTTPプロトコルハンドラーは、システムにデフォルトのCookieHandlerインスタンスがあるかどうかを確認します。 存在する場合、それを呼び出して状態管理を担当します。

したがって、CookieHandlerクラスには、HTTPプロトコルハンドラーの利益のためにコールバックメカニズムを提供する目的があります。

CookieHandlerは抽象クラスです。 現在のCookieHandlerインストールを取得するために呼び出すことができる静的なgetDefault()メソッドがあります。または、setDefault(CookieHandler)を呼び出して独自のインストールを設定することもできます。 setDefaultを呼び出すと、システム全体でCookieHandlerオブジェクトがインストールされることに注意してください。

また、CookieをCookieストアに保存するためのput(uri, responseHeaders)もあります。 これらのCookieは、指定されたURIからのHTTP応答の応答ヘッダーから取得されます。 応答を受信するたびに呼び出されます。

関連するAPIメソッド–get(uri,requestHeaders)は、指定されたURIで保存されたCookieを取得し、それらをrequetHeadersに追加します。 リクエストが行われる直前に呼び出されます。

これらのメソッドはすべて、CookieHandlerの具象クラスで実装する必要があります。 この時点で、CookieManagerクラスは注目に値します。 このクラスは、最も一般的なユースケース向けにCookieHandlerクラスの完全な実装を提供します。

次の2つのセクションでは、CookieManagerクラスについて説明します。最初はデフォルトモードで、後でカスタムモードで。

4. デフォルトのCookieManager

完全なCookie管理フレームワークを作成するには、CookiePolicyCookieStoreを実装する必要があります。

CookiePolicyは、Cookieを受け入れたり拒否したりするためのルールを確立します。 もちろん、これらのルールをニーズに合わせて変更できます。

次へ–CookieStoreは、その名前が示すとおりに実行します。Cookieを保存および取得するためのメソッドがあります。 必要に応じて、ここでもストレージメカニズムを微調整できます。

まず、デフォルトを見てみましょう。 デフォルトのCookieHandlerを作成し、それをシステム全体のデフォルトとして設定するには、次のようにします。

CookieManager cm = new CookieManager();
CookieHandler.setDefault(cm);

デフォルトのCookieStoreには揮発性メモリがあることに注意してください。 JVMの存続期間中のみ有効です。 Cookieの永続的なストレージを確保するには、カスタマイズする必要があります。

CookiePolicyに関しては、デフォルトの実装はCookiePolicy.ACCEPT_ORIGINAL_SERVERです。 これは、応答がプロキシサーバー経由で受信された場合、Cookieが拒否されることを意味します。

5. カスタムCookieManager

次に、CookiePolicyまたはCookieStore(またはその両方)の独自のインスタンスを提供して、デフォルトのCookieManagerをカスタマイズしましょう。

5.1. CookiePolicy

CookiePolicyは、便宜上、いくつかの事前定義された実装を提供します。

  • CookiePolicy.ACCEPT_ORIGINAL_SERVER –元のサーバーからのCookieのみを保存できます(デフォルトの実装)

  • CookiePolicy.ACCEPT_ALL –すべてのCookieは、その発信元に関係なく保存できます

  • CookiePolicy.ACCEPT_NONE –Cookieを保存できません

独自の実装を行わずに現在のCookiePolicyを単純に変更するには、CookieManagerインスタンスでsetCookiePolicyを呼び出します。

CookieManager cm=new CookieManager();
cm.setCookiePolicy(CookiePolicy.ACCEPT_ALL);

ただし、これよりもはるかに多くのカスタマイズを行うことができます。 CookiePolicy.ACCEPT_ORIGINAL_SERVERの動作を知っているので、特定のプロキシサーバーを信頼し、元のサーバー上でそのサーバーからCookieを受け入れたいと仮定します。

CookiePolicyインターフェースを実装し、shouldAcceptメソッドを実装する必要があります。ここで、選択したプロキシサーバーのドメイン名を追加して、承認ルールを変更します。

新しいポリシーをProxyAcceptCookiePolicyと呼びましょう。 基本的に、指定されたプロキシアドレス以外のshouldAccept実装から他のプロキシサーバーを拒否し、CookiePolicy.ACCEPT_ORIGINAL_SERVERshouldAcceptメソッドを呼び出して実装を完了します。

public class ProxyAcceptCookiePolicy implements CookiePolicy {
    private String acceptedProxy;

    public boolean shouldAccept(URI uri, HttpCookie cookie) {
        String host = InetAddress.getByName(uri.getHost())
          .getCanonicalHostName();
        if (HttpCookie.domainMatches(acceptedProxy, host)) {
            return true;
        }

        return CookiePolicy.ACCEPT_ORIGINAL_SERVER
          .shouldAccept(uri, cookie);
    }

    // standard constructors
}

ProxyAcceptCookiePolicyのインスタンスを作成するとき、元のサーバーに加えて、Cookieを受け入れたいドメインアドレスの文字列を渡します。

次に、このインスタンスをCookieManagerインスタンスのCookieポリシーとして設定してから、デフォルトのCookieHandlerとして設定します。

CookieManager cm = new CookieManager();
cm.setCookiePolicy(new ProxyAcceptCookiePolicy("example.com"));
CookieHandler.setDefault(cm);

このようにして、Cookieハンドラーは元のサーバーからのすべてのCookieとhttp://www.example.comからのCookieを受け入れます。

5.2. CookieStore

CookieManagerは、すべてのHTTP応答のCookieStoreにCookieを追加し、すべてのHTTP要求のCookieStoreからCookieを取得します。

デフォルトのCookieStore実装には永続性がなく、JVMを再起動するとすべてのデータが失われます。 コンピュータのRAMに似ています。

したがって、CookieStoreの実装をハードディスクのように動作させ、JVMの再起動後もCookieを保持する場合は、ストレージと取得のメカニズムをカスタマイズする必要があります。

注意すべき点の1つは、作成後にCookieStoreインスタンスをCookieManagerに渡すことができないことです。 唯一のオプションは、CookieManagerの作成中にそれを渡すか、新しいCookieManager().getCookieStore()を呼び出してその動作を補完することにより、デフォルトインスタンスへの参照を取得することです。

PersistentCookieStoreの実装は次のとおりです。

public class PersistentCookieStore implements CookieStore, Runnable {
    private CookieStore store;

    public PersistentCookieStore() {
        store = new CookieManager().getCookieStore();
        // deserialize cookies into store
        Runtime.getRuntime().addShutdownHook(new Thread(this));
    }

    @Override
    public void run() {
        // serialize cookies to persistent storage
    }

    @Override
    public void add(URI uri, HttpCookie cookie) {
        store.add(uri, cookie);

    }

    // delegate all implementations to store object like above
}

コンストラクターで既定の実装への参照を取得したことに注意してください。

JVMがシャットダウンしているときに実行されるシャットダウンフックを追加できるように、runnableを実装します。 runメソッド内で、すべてのCookieをメモリに保持します。

データをファイルまたは適切なストレージにシリアル化できます。 コンストラクター内で、最初にすべてのCookieを永続メモリからCookieStoreに読み込むことにも注意してください。 これらの2つの単純な機能により、デフォルトのCookieStoreは本質的に永続的になります(単純化された方法で)。

6. 結論

このチュートリアルでは、HTTP Cookieを取り上げ、プログラムでそれらにアクセスして操作する方法を示しました。

記事の完全なソースコードとすべてのコードスニペットは、GitHub projectにあります。