前回はJSPでセッションを扱う方法を説明しました。JSPのセッションでは、セッションの識別IDがクッキーとして自動的にブラウザ側に格納されていました。今回は、このクッキーの扱いについて、JSPプログラムから値の格納と取得を行う方法について説明します。
クッキーとは
クッキーという概念がなかったころのWebシステムでは、サーバ側でアプリケーションを提供できても、ブラウザやユーザーが利用している端末にデータを書き込むことはできませんでした。クッキーは、その問題を解決するために考案された技術です。
クッキーがサポートされるブラウザに対して、サーバが小さなデータ(name=valueの組み合わせ:クッキー)をレスポンスのヘッダ部分に記述することで、その内容をブラウザ側に保存できます。ブラウザ側は、次回そのクッキーを発行したサイトに訪れた際に、持っているクッキーをサーバに提出します。サーバはその内容を確認することにより、前回自分がブラウザとやりとりしたデータを復元できます(図1)。
クライアント側がクッキーを受け取った後は、ブラウザを閉じたり、コンピュータの電源を切ってもクッキーの情報を再度利用することができます。また、クッキーには有効期限を設定できるので、特定の期間を過ぎたクッキーを無効にすることができます。
今日のWebアプリケーションでは、このクッキーを利用して、次のようなことが行われています。
- 会員サイトのユーザーIDを保存して、次回の訪問でユーザーを認識する
- 最後に訪れた日時を保存して、ユーザーの訪問頻度を計る
- ユーザーがカスタマイズしたサイトの情報(ユーザーのし好)を保存しておき、次回もその設定を適用する
- 掲示板へ投稿するときに入力した名前とメールアドレスを保存しておき、次回の入力の手間を省く
クッキーを使用するJSPプログラムの例
それでは、実際にクッキーを用いた例を見てみましょう。今回のプログラムは、8-1.jsp、8-2.jsp、8-3.jspの3つのJSPページから構成され、それぞれ次のような処理を行います。
8-1.jsp | ・このページにアクセスした時刻を文字列としてクッキーに設定する |
---|---|
8-2.jsp | ・8-1.jspで設定されたクッキーを取得して内容を表示する。クッキーが取得できなかった場合はその旨のメッセージを表示する |
8-3.jsp | ・クッキーを破棄する(有効期間がゼロ秒のクッキーを設定する) |
実際のプログラムの内容は次のようになります。
<%@ page import="java.net.*, java.util.Date" contentType="text/html; charset=euc-jp" %> <% // 内容: クッキーを使用する(クッキーの設定) // 現在の時刻を取得 Date now = new Date(); // クッキーに格納する文字列を作成(URLエンコードをする) String value = URLEncoder.encode(now.toString()); // 名前が"accesstime"、値が現在時刻であるクッキーを作成 Cookie cookie = new Cookie("accesstime",value); // クッキーの設定 cookie.setMaxAge(7 * 24 * 60 * 60); //有効期間を1週間に設定 // クッキーを発行 response.addCookie(cookie); %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head><title>クッキーを使用する</title></head> <body> <p>-- クッキーの設定 --</p> <p>このページにアクセスした時刻をクッキーに設定しました。</p> <p><a href="8-2.jsp">クッキーの内容を確認する</a></p> </body> </html>
まず、7行目と10行目で、クッキーに格納する値の準備をしています。前回の記事で説明したsessionには、任意の型のオブジェクトを格納できましたが、クッキーに格納できるオブジェクトは文字列(String)だけです。また、HTTPプロトコルでは、cookieの値として使用できる文字の種類に制限がありますので、値をURLエンコードしてから設定するようにします。具体的には、10行目の記述のように、java.net.URLEncoderクラスのencode()メソッドを使用します。
9: // クッキーに格納する文字列を作成(URLエンコードをする) 10: String value = URLEncoder.encode(now.toString());
java.net.URLEncoderクラスを使用するために、1行目で java.net.*パッケージのインポートを宣言しています。encode()メソッドはスタティックなので、インスタンスを生成せずに使用できます。
さて、13行目ではCookieのインスタンスを生成しています。Cookieのコンストラクタは、
Cookie(java.lang.String name, java.lang.String value)
のみです。クッキーを識別するための名前と、格納する文字列を引数に指定します。
16行目では、クッキーの有効期間を1週間に設定しています。setMaxAgeによる有効期間の指定は秒単位で行います。
このほかにも、クッキーに対しては参照可能なパスの設定やコメント、バージョンなど各種の設定が可能ですが、ここでは簡単のために有効期間のみの設定を行っています。そのほかの項目を設定するメソッドは本稿の最後にまとめてあります。
クッキーの発行は、暗黙オブジェクトの1つであるresponseオブジェクトの以下のメソッドを使用します。
addCookie(Cookie cookie)
19行目で、実際に作成したクッキーを引数として、このメソッドを実行しています。
18: // クッキーを発行 19: response.addCookie(cookie);
実際には、サーバからブラウザ側に対してレスポンスが送り出されるときに、ヘッダ情報の一部としてクッキーの情報も送り出されます。
続いて、クッキーの内容を取得する8-2.jspのプログラムの内容は次のようになります。
<%@ page import="java.net.*" contentType="text/html; charset=euc-jp" %> <% // 内容: クッキーを使用する(クッキーの取得) // クッキーの配列を取得 Cookie cookies[] = request.getCookies(); // 目的のクッキーを格納する変数 Cookie accesstimeCookie = null; // それぞれのクッキーに対して名前を確認 if(cookies != null) { for(int i = 0; i < cookies.length; i++) { // 名前が "accesstime" であるかチェック if(cookies[i].getName().equals("accesstime")) { // 該当するクッキーを取得 accesstimeCookie = cookies[i]; } } } // 表示する文字列 String accesstime; // 該当するクッキーがみつからなかった場合 if(accesstimeCookie == null) { accesstime = "記録がありません"; } else { // クッキーがみつかった場合は値を取得(URLデコードする) accesstime = URLDecoder.decode(accesstimeCookie.getValue()); } %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head><title>クッキーを使用する</title></head> <body> <p>-- クッキーの取得 --</p> <p>8-1.jsp に最後にアクセスした時刻<br> <b>[ <%= accesstime %> ]</b> <p><a href="8-1.jsp">クッキーを設定する</a> | <a href="8-3.jsp">クッキーを破棄する</a></p> </body> </html>
クッキーの取得は、クッキーの設定に比べて少々やっかいです。
暗黙オブジェクトの1つであるrequestオブジェクトの、
getCookies()
メソッドを使用してクッキーを取得しますが、このメソッドでは個別のクッキーではなく、複数のクッキーをひとまとまりの配列として取得します。そのため、この配列から目的のクッキーを探し出すための処理があらためて必要になります。
まず7行目でクッキーの配列を取得し、14〜20行目のforループの中で目的のクッキーを探しています。クッキーの名前はCookieオブジェクトのgetName()メソッドで取得できるため、次のような if 文で、名前の比較をして目的のクッキーであるかどうかを判定できます。
16: if(cookies[i].getName().equals("accesstime")) { 17: // 該当するクッキーを取得 18: accesstimeCookie = cookies[i]; 19: }
さて、目的のクッキーを見つけることができた後は、getValue()メソッドで格納されている値(文字列)を取得します。ここで格納された文字列はURLエンコードされたものなので、URLデコードの処理が必要になることに注意しましょう。
URLエンコードされた文字列は、java.net.URLDecodeクラスのdecode()メソッドで元の文字列に復元できます。エンコードの処理と同様、decode()メソッドはスタティックなので、インスタンスを生成せずに使用できます。
これらの、クッキーからの値の取得とURLデコードの処理は30行目で行っています。
30: accesstime = URLDecoder.decode(accesstimeCookie.getValue());
もし、目的のクッキーが見つからなかった場合は、
28: accesstime = "記録がありません";
とし、その結果を40行目でHTML文に出力しています。
39: <p>8-1.jsp に最後にアクセスした時刻<br> 40: <b>[ <%= accesstime %> ]</b>
続いて、クッキーの破棄を行う8-3.jspのプログラムの内容は次のようになります。
<%@ page contentType="text/html; charset=euc-jp" %> <% // 内容: クッキーを使用する(クッキーを破棄する) // クッキーを作成 Cookie cookie = new Cookie("accesstime",""); // クッキーの有効期間を0秒に設定 cookie.setMaxAge(0); // クッキーを発行 response.addCookie(cookie); %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head><title>クッキーを使用する</title></head> <body> <p>-- クッキーの破棄 --</p> <p>クッキーの内容を削除しました。</p> <p><a href="8-2.jsp">クッキーの内容を確認する</a></p> </body> </html>
8-3.jspは、クッキーの破棄を行います。クッキーの破棄といっても、明示的にクッキーの内容を削除する手段はないため、既存のクッキーを有効期間がゼロ秒のクッキーに変更することで、ブラウザ側で破棄の処理を行うように促します。
6行目でクッキーを作成していますが、クッキーの名前は、削除したいクッキーの名前にします。次に、9行目で、クッキーの有効期間をゼロ秒に設定しています。
5:// クッキーを作成 6: Cookie cookie = new Cookie("accesstime",""); 7: 8: // クッキーの有効期間を0秒に設定 9: cookie.setMaxAge(0);
12行目で、このクッキーの発行を行っていますが、これは8-1.jspの方法とまったく同じです。
さて、再度8-2.jspへアクセスすることで、この方法で本当にクッキーが削除されたのかどうかを確認できます。20行目で、8-2.jspへのリンクを表示しています。
プログラムの実行結果
実際に上記のプログラムを実行してみましょう。一連の処理の流れは次のようになります(上から下の順に遷移します)。
■Cookieクラスのメソッド
簡単なサンプルプログラムをもとに、クッキーの作成とその格納、および取得の様子を見てきました。ここで述べた以外にも、Cookieクラスには多くのメソッドがあり、クッキーの振る舞いを細かく設定できるようになっています。Cookieクラスの振る舞いを設定するそのほかのメソッドには次のようなものがあります。
メソッド | 説明 | |
---|---|---|
setComment(java.lang.String purpose) | クッキーの目的を説明するためのコメント文を設定します(クッキーのバージョンが1以上である場合に使用されます) | |
setDomain(java.lang.String pattern) | クッキーにアクセス可能なサーバまたはドメインを設定します | |
setPath(java.lang.String uri) | クッキーにアクセス可能なURLパスを設定します | |
setSecure(boolean flag) | HTTPSなどの暗号化されたセキュアなプロトコルで送られるかどうかを指定します | |
setVersion(int v) | クッキーのバージョンを指定します |
今回はJSPでのクッキーの扱いについて解説しました。次回は、JSPでのページ転送処理について説明します。
Copyright © ITmedia, Inc. All Rights Reserved.