本連載では、これまでブラウザで表示される内容の1ページ1ページがそれぞれ独立しているものを扱ってきました。しかしながら、処理の内容によっては、異なるページ間で特定のデータを共有するなど、複数のページを1つの連続したものとして扱いたい場合があります。この場合、セッションの知識が必要になります。今回は、セッションの扱いについて説明します。
JSPでは、暗黙オブジェクトの1つであるsessionオブジェクトを使用することで、一続きの処理の中で共通のデータ(オブジェクト)を扱うセッションという概念を実現することができます。
通信ソフトなどにおける「セッション」とは、「互いの接続が確立してから切断をするまで」のことであり、同一セッションの間は、互いを認識しながら通信を行います。HTTP通信の場合は、1つのURLに対するリクエストから、そのレスポンスが返されるまでが1つのセッションになります。
例えば、特定のページにアクセスした場合、ブラウザがサーバへリクエストを出し、その応答としてページの内容を受け取るまでが1セッションであり、ページ内にあるリンクをたどって次のページへアクセスした場合は、また別のセッションが開始されることになります(図1)。
しかしながら、実際にWebアプリケーションを作成するうえでは、複数のページにわたる処理を1つのセッションとして扱いたい場合があります。例えばショッピングサイトを構築する際には、商品選びから購入まで1人の顧客を識別し、一連のサービスを提供するような仕組みを作る必要があります(図2)。
HTTPの範囲では、このようなセッションを扱うことができないため、JSPではクッキーを使用して複数ページにわたるセッションを管理する仕組みが準備されています。
具体的には、ユーザーが最初にサイトにアクセスしたときに、1つのセッションが開始されたと見なし、セッションを識別するためのセッションIDがブラウザ側にクッキーとして発行されます(第4回で表示した画面「ヘッダ情報の取得」の中に含まれていた 変数名[cookie]、値[JSESSIONID=f2c9x1oft1]がこれに当たります)。それ以降のアクセスでは、このクッキーに格納されたセッションIDによってセッションの認識を行うことで、HTTP上で複数のページにわたるセッションの管理を可能にしています。セッションごとに関連付けられたセッション変数は、サーバ側で管理されます(図3)。
このようなセッションの仕組みを用いることで、アプリケーション側では次のようなことができます。
ブラウザ側ではクッキーを受け取れるように設定している必要があります。
それでは、実際にセッションを用いた例を見てみましょう。今回のプログラムは、7-1.jsp、7-2.jsp、7-3.jspの3つのJSPページから構成され、それぞれ次のような処理を行います。
7-1.jsp | ・セッション変数にユーザー名が格納されていれば「ようこそ○○さん」というメッセージと、7-3.jspへのリンクを表示する ・ユーザー名が格納されていなければ、入力用のフォームを表示し、値を7-2.jspへ渡す |
---|---|
7-2.jsp | ・7-1.jspで入力されたユーザー名をセッション変数に格納する |
7-3.jsp | ・セッションを終了させて、セッション変数を解放する |
実際のプログラムの内容は次のようになります。
<%@ page contentType="text/html; charset=euc-jp" %> <% // 内容: セッションを使用する // セッション変数の取得 String userName = (String)session.getAttribute("name"); // 表示するメッセージ String message = ""; if(userName == null) { // セッション変数 name を取得できなかった場合 message = "お名前を入力してください。<br>" + "<form action=\"7-2.jsp\">" + "<input type=\"text\" name=\"name\" size=16> " + "<input type=\"submit\" value=\"OK\">"; } else { // セッション変数 name を取得できた場合 message = "ようこそ <b>" + userName + "</b> さん。<br><br>" + "<a href=\"7-3.jsp\">セッションを終了する</a>"; } %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head><title>セッションを使用する</title></head> <body> <p>-- セッション変数の取得 --</p> <p><%= message %></p> <p>(sessionID=<%= session.getId() %>)</p> </body> </html>
まず、6行目でセッション変数の取得を行っています。
nameという文字列で指定される変数を取得し、結果を文字列userNameに代入しています。セッション変数の取得には、sessionオブジェクトのメソッド
getAttribute(java.lang.String name)
を使用します。
sessionオブジェクトは、outオブジェクトと同様、JSP側で初めから準備されている暗黙オブジェクトの1つです。
セッション変数には任意のオブジェクトを格納することができるので、取得する内容がString型のオブジェクトであることを(String)によって明示的に記しています(この操作をキャストといいます)。
11〜20行目のif〜else構文で、このセッション変数を実際に取得できた場合(userNameがnullでなかったら)、その文字列を使用して「ようこそ○○さん」のメッセージを表示し、取得できなかった場合は名前を入力してもらうためのフォームを表示するようにしています。表示する内容をそれぞれString型のmessage変数に代入しています。
27行目で、このmessageの内容を表示しています。また、28行目では確認用にセッションの識別IDも併せて表示しています。セッションの識別IDはgetId()メソッドで取得できます。
27: <p><%= message %></p> 28: <p>(sessionID=<%= session.getId() %>)</p>
続いて、7-2.jspのプログラムの内容は次のようになります。
<%@ page contentType="text/html; charset=euc-jp" %> <% // 内容:受け取ったパラメータをセッションに格納する // パラメータの取得 String name = request.getParameter("name"); // 文字コードの変換 name = new String(name.getBytes("8859_1"), "EUC_JP"); // セッション変数の格納 session.setAttribute("name", name); %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head><title>セッションを使用する</title></head> <body> <p>-- セッション変数の格納 --</p> <p> 次の内容をセッションに格納しました<br> name = <%= name %><br> <br> <a href="7-1.jsp">戻る</a> </p> <p>(sessionID=<%= session.getId() %>)</p> </body> </html>
7-2.jspは、7-1.jspのフォームで入力された名前を受け取り、それをセッション変数として格納します。
パラメータで渡される文字列には、日本語が含まれることがあるため、9行目で、前処理として文字コードの変換をしています。
セッション変数の格納は12行目で行っています。
12: session.setAttribute("name", name);
セッション変数をsessionオブジェクトに格納するには、以下のメソッドを使用します。
setAttribute(java.lang.String name, java.lang.Object value)
特定の文字列をキーに、任意の型のオブジェクトを格納できます。
その後、先ほどの7-1.jspに戻るリンクと、セッションの識別IDを出力します。続いて、7-3.jspのプログラムの内容は次のようになります。
<%@ page contentType="text/html; charset=euc-jp" %> <% // 内容:セッションを終了する // セッションの終了(セッション変数の解放) session.invalidate(); %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head><title>セッションを使用する</title></head> <body> <p>-- セッションの終了 --</p> <p>セッションを終了して、セッション変数を解放しました <br> <a href="7-1.jsp">戻る</a> </p> <p>(sessionID=<%= session.getId() %>)</p> </body> </html>
7-3.jspは、セッションを終了して、セッション変数の解放を行います。この処理は6行目の、
6: session.invalidate();
の記述で行っています。セッションを終了するには、以下のメソッドを使用します。
invalidate()
この処理により、セッション変数として格納されているオブジェクトがガーベッジコレクションの対象となります。次のアクセスから、再度新しいセッションが開始することになります。
さて、実際に上記のプログラムを実行してみましょう。一連の処理の流れは次のようになります(上から下の順に遷移します)。
簡単なサンプルプログラムをもとに、セッション変数の格納と取得の様子を見てきました。上で述べた以外にも、sessionオブジェクトのそのほかの主なメソッドには次のようなものがあります。
メソッド | 説明 | |
---|---|---|
long getCreationTime() | セッションの作成時刻を取得する | |
java.lang.String getId() | セッションIDを取得する | |
long getLastAccessedTime() | 最後にアクセスした時刻を取得する | |
int getMaxInactiveInterval() | リクエストがなかった場合にセッションを終了するまでの時間を取得する(秒) | |
void invalidate() | セッション変数を解放し、セッションを終了する | |
boolean isNew() | セッションIDがユーザーのブラウザにとって新規のものであるかどうかを取得する | |
void setMaxInactiveInterval(int interval) | リクエストがなかった場合にセッションを終了するまでの時間を設定する(秒) | |
今回はJSPでのセッションの扱いについて解説しました。ところで、JSPのセッション管理に用いるセッションの識別IDは、クライアント側にクッキーとして格納されます。セッションに用いられるクッキーは、自動的に発行、取得されるため、今回はクッキーの仕組みを意識する必要がありませんでした。次回は、この「クッキー」の扱いについて、より詳しく説明します。
Copyright © ITmedia, Inc. All Rights Reserved.