ASH | サーバ | セキュリティ | Linux | FreeBSD | DB | Web | CGI | Perl | Java | XML | プログラム | ネットワーク | 標準 | Tips集

セッションのタイムアウトと開始終了処理

セッション管理

 サーブレット+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>


Copyright (C)1995-2002 ASH multimedia lab.
mail : info@ash.jp