サーブレット+JSP+データクラス/Beanを使った、セッション管理の方法について解説します。
HTTPプロトコルでは、1回のリクエストに対して、画面を表示して終了してしまいます。
従って、複数の画面に渡って処理を行う場合には、セッション管理が必要となります。
サーブレットにはセッション管理機能があり、複数のHTTPプロトコルにまたがるデータを管理することができます。
サーブレットでセッション管理をするためには、getSession()メソッドを呼び出します。
ここでは、インスタンス変数名は、sessionとしています。
HttpSession session = req.getSession(); |
セッション変数は、HttpServletRequestの属性として、setAttribute()メソッドで設定し、getAttribute()メソッドで参照します。 また、リソースを有効に利用するため、removeAttribute()メソッドで削除することもできます。
// セッション変数の作成と設定 インスタンス変数名 = new データクラス名(); session.setAttribute("セッション変数名", インスタンス変数名); // セッション変数の取得 データクラス名 インスタンス変数名 = (データクラス名) session.getAttribute("セッション変数名"); // セッション変数の削除 session.removeAttribute("セッション変数名"); |
Webアプリケーションでは、コンテナがセッションを行います。
HTTPプロトコルでは、セッションという概念はありませんので、タイムアウト時間によりセッションを切断します。
セッションのタイムアウト時間(分単位)は、デプロイメント記述子(web.xml)に設定します。
利用者が、ログイン、ログアウトしないシステムでは、タイムアウトするまで、セッション変数は残りリソースを消費します。
ですから、インターネットなどに公開するシステムの場合、タイムアウト値は3分から5分ぐらいの短い値に設定します。
社内システムのように、利用者が、ログイン、ログアウトをする場合は、30分や1時間ぐらいに設定しても、問題ありません。
<session-config> <session-timeout>5</session-timeout> </session-config> |
セッション開始時や終了時に、セッションでの前処理や後処理が必要な場合があります。 このような場合、javax.servlet.http.HttpSessionBindingListenerインターフェイスを利用します。 valueBound()は、setAttribute()実行時に呼び出されます。 valueUnbound()は、removeAttribute()実行時と、セッションタイムアウト時に呼び出されます。
public interface HttpSessionBindingListener { void valueBound (HttpSessionBindingEvent event); void valueUnbound (HttpSessionBindingEvent event); } |
セッションの終了処理は、removeAttribute()メソッドを呼び出すことで、終了することができます。
しかし、タイムアウトになる前に、再度呼び出すと、同じセッションとなってしまいます。
ですから、戻るボタンなどで、以前のセッションを表示すると、誤動作する可能性が出てきます。
このような場合は、invalidate()メソッドを呼び出すことで解決できます。
invalidate()メソッドは、セッションを無効としますので、次にアクセスした場合は、別のセッションとなります。
invalidate()メソッドを発行すると、removeAttribute()メソッドも呼び出されるため、valueUnbound()メソッドも呼び出されます。
session.invalidate(); |
セッション開始画面で、logoutボタンを押すと、セッション終了画面を表示します。
また、セッション開始画面で、5分以上何もしなくても、自動的にログアウトされます。(この場合、画面の表示は変わりません。)
パラメータなしの場合は、セッション開始画面を表示し、パラメータに「act=lo」を指定すると、セッション終了画面を表示します。 logoutボタンを押すと、「act=lo」を指定して、サーブレットを呼び出しています。
SessionServlet.java |
---|
// Copyright (C)1995-2002 ASH multimedia lab. http://ash.jp/ package jp.ash.example; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** セッション開始終了処理のテストサーブレット **/ public class SessionServlet extends HttpServlet { public void service (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HttpSession session = req.getSession(); res.setContentType("text/html; charset=Shift_JIS"); req.setCharacterEncoding("Shift_JIS"); PrintWriter out = res.getWriter(); SessionData data; // パラメータの取得 String act = req.getParameter("act"); // ログイン処理 if (act == null) { // セッション変数の作成、設定 data = new SessionData(); session.setAttribute("data", data); // セッション開始画面の表示 out.println("<html><body>"); out.println("<h1>セッション開始</h1>"); out.println("<form method=\"POST\" action=\"SessionServlet?act=lo\">"); out.println("<input type=\"submit\" value=\"logout\">"); out.println("</form>"); out.println("</body></html>"); out.close(); // ログアウト処理 } else { // セッション終了画面の表示 out.println("<html><body>"); out.println("<h1>セッション終了</h1>"); out.println("</body></html>"); out.close(); // セッションの無効化 session.invalidate(); } } } |
データクラスでは、HttpSessionBindingListenerインターフェイスをimplementsします。
setAttribute()実行時に、valueBound()メソッドが呼び出され、removeAttribute()実行時と、セッションタイムアウト時に、valueUnbound()メソッドが呼び出されます。
valueBound()メソッドや、valueUnbound()メソッドが呼ばれると、コンテナの起動画面に、「valueBound」「valueUnbound」という文字列を表示しているため、動作確認できます。
SessionData.java |
---|
// Copyright (C)1995-2002 ASH multimedia lab. http://ash.jp/ package jp.ash.example; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** セッションテストデータ **/ public class SessionData implements HttpSessionBindingListener { /** セッション開始時の処理 **/ public void valueBound (HttpSessionBindingEvent event) { System.out.println("valueBound"); } /** セッション終了時の処理 **/ public void valueUnbound (HttpSessionBindingEvent event) { System.out.println("valueUnBound"); } } |
Sessionサーブレットを起動すると、「ValueBound」が表示されます。
logoutボタンを押したときと、セッションタイムアウト(5分間)した時に、「valueUnbound」が表示されることを確認します。
valueBound (Sessionサーブレットを起動した時に表示) valueUnbound (logoutボタンを押下した時に表示) valueBound (Sessionサーブレットを再起動した時に表示) valueUnbound (セッションタイムアウトした時に表示) |
サーブレットをweb.xmlに登録します。 また、セッションのタイムアウト値もweb.xmlに登録します。 この例では、5分に設定しています。
web.xml |
---|
<?xml version="1.0" ?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>SessionServlet</servlet-name> <servlet-class>jp.ash.example.SessionServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>SessionServlet</servlet-name> <url-pattern>/SessionServlet/*</url-pattern> </servlet-mapping> <session-config> <session-timeout>5</session-timeout> </session-config> </web-app> |