1. 概要

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

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

import java.net.*;

2. HTTPクッキー

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

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

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

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

3. CookieHandlerクラス

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

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

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

CookieHandlerは抽象クラスです。 静的なgetDefault()メソッドがあり、これを呼び出して現在の CookieHandler インストールを取得するか、 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管理フレームワークを使用するには、CookiePolicyおよびCookieStoreを実装する必要があります。

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

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

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

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

デフォルトのCookieStoreには揮発性メモリがあることに注意してください。 JVMの存続期間中のみ存続します。 Cookieをより永続的に保存するには、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("baeldung.com"));
CookieHandler.setDefault(cm);

このようにして、Cookieハンドラーは、元のサーバーからのすべてのCookieと、http://www.baeldung.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
}

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

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

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

6. 結論

このチュートリアルでは、HTTP Cookieについて説明し、プログラムでCookieにアクセスして操作する方法を示しました。

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