HttpSession イベントのリスン

HttpSession オブジェクトには、ステートを簡単かつ強力に管理できるようにする API が用意されています。HttpSession オブジェクトにはイベントリスナが 3 つあります。

ServletContext リスナの場合と同様に、JRun はイベントオブジェクトをセッションリスナ内の各メソッドに渡します。リスナはこれらのオブジェクトを介して Session オブジェクト、Session オブジェクトの属性、および ServletContext オブジェクトにアクセスできます。

HttpSession イベントが発生すると、これらのインターフェイスが実装しているメソッドをトリガーできます。次の表に、これらのインターフェイスのメソッドと、JRun にこれらのメソッドを呼び出させるイベントを示します。
メソッド
このメソッドに通知するイベント
HttpSessionListener インターフェイス
sessionCreated
JRun が新規 HttpSession オブジェクトを作成します。
request.getSession(true) を呼び出します。
sessionDestroyed
HttpSession がタイムアウトになります。
session.invalidate を呼び出します。
HttpSessionAttributeListener インターフェイス
attributeAdded
HttpSession オブジェクトに属性を追加します。
session.setAttribute を呼び出して属性を追加
します。
attributeReplaced
HttpSession オブジェクトの属性の値を変更します。
属性に対して session.setAttribute を呼び出します。
attributeRemoved
HttpSession 属性を削除します。
JRun サーバを停止または再起動します。
session.removeAttribute を呼び出します。
HttpSessionActivationListener インターフェイス
sessionWillPassivate
JRun が HttpSession オブジェクトをパッシベート
します。
sessionDidActivate
JRun が以前にパッシベートされた HttpSession
オブジェクトをアクティブにします。

HttpSessionListener について

HttpSessionListener を使用して、ロギングまたはパーシスタンスコードをアプリケーションに入れることができます。このリスナは、アプリケーションにログインしているユーザーの数を追跡する際にも役立ちます。この例では、セッションが作成されるたびにカウンタを 1 つ増やし、セッションが廃棄されるたびに 1 つ減らします。

次の行のように、セッションを作成するリソースがリクエストされると、JRun はセッションを作成します。

HttpSession session = request.getSession(true);

次の行のように、セッションがタイムアウトになるか、明示的に廃棄されると、JRun はセッションを廃棄します。

session.invalidate();

クライアントからのリクエストなしに MaxInactiveInterval が経過すると、セッションはタイムアウトになります。JRun がタイムアウトになるまでのデフォルト設定は 1800 秒 (30 分) です。セッション設定の詳細については、『JRun 管理者ガイド』を参照してください。

セッションオブジェクトは Cookie オブジェクトとして頻繁にインスタンス化されます。それによって、Cookie オブジェクトとしてセッションでオペレーションを実行できますが、制限もあります。たとえば、Cookie の MaxAge が -1 に設定されている場合は、ブラウザを閉じたときにクライアント上で Cookie が廃棄されます。サーバはクライアントが閉じたことを検出できないため、HttpSessionListener.sessionDestroyed イベントは通知されません。

JRun は、セッションオブジェクトが最初に作成または廃棄されたときに、次のメソッドを使用して HttpSessionListener に通知します。

HttpSessionListenerEvent オブジェクトには次の 1 つのメソッドがあります。

getSession()

HttpSessionAttributeListener について

JRun は、Session オブジェクトの属性が追加または削除されるか、または Session オブジェクトの属性の値が変更されると、次のメソッドを使用して HttpSessionAttributeListener に通知します。

Session オブジェクトの属性は、HttpSession オブジェクトのみがアクセス可能です。ServletContext のオブジェクト名に合わせるには、イベントオブジェクト
HttpSessionBindingEvent の名前を HttpSessionAttributeEvent とする方が適切です。

HttpSessionBindingEvent オブジェクトは HttpSessionEvent オブジェクトから getSession メソッドを継承します。セッション属性にアクセスできるメソッドが他に 2 つあります。

HttpSessionListener のロギング例

単純な HttpSession イベントリスナの例を次に示します。このイベントリスナは
HttpSessionListener のメソッドを実装します。これらのいずれかのイベントが発生すると、標準出力に行が出力されます。セッションが作成されると、このリスナはセッション ID と作成日を標準出力に出力します。

...
public final class SessionLogger implements HttpSessionListener {
 public void sessionCreated(HttpSessionEvent event) {
  System.out.println("作成されたセッション");
  HttpSession session = event.getSession();
  String sid = session.getId();
  long time = session.getCreationTime();
  System.out.println("新規セッション ID:" + sid);
  System.out.println("作成されたセッション @ " + time);
 }
 public void sessionDestroyed(HttpSessionEvent event) {
  System.out.println("セッション " + event.getSession().getId() + " 廃棄");
 }
}

データベースでのセッション情報の保管

HttpSession リスナの用途の 1 つに、セッションを保管および追跡するためのコードの集中化があります。すべてのデータベースコードをリスナに入れ、サーブレットと JSP を保管すると、追跡情報の詳細とは別にセッションオブジェクトを操作できます。

さまざまなイベントの呼び出しを予測できるため、このセットアップは、Sun の『Core J2EE Patterns』に記載されている Intercepting Filter パターン (Decorator Filter パターンとも呼ばれる) に似ています。

サンプルの JRun サーバでは、次のリスナを実装します。

package jrunsamples.events;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
public final class SessionWatcher implements HttpSessionListener {
 public void sessionCreated(HttpSessionEvent event) {
//Session オブジェクトを介して ServletContext オブジェクトにアクセスすることもでき
ます。
  String datasource_name = (String) event.getSession(). 
getServletContext().getAttribute("datasource_name");
  HttpSession session = event.getSession();
  String sid = session.getId();
  long time = session.getCreationTime();
  //セッション ID、作成日、およびセッション変数の値をデータベースに追加します。
  String sqlstmt = "INSERT INTO SESSIONS VALUES(?,?,?)";
  try {
   InitialContext ctx = new InitialContext();
   DataSource ds = (DataSource) ctx.lookup(datasource_name);
   Connection conn = ds.getConnection();
   PreparedStatement ps = conn.prepareStatement(sqlstmt);
   ps.setString(1,sid);
   ps.setLong(2,time);
   ps.setInt(3, 1); //デフォルト値は 1 に設定されています。
   ResultSet rs = ps.executeQuery();
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   try {
    ps.close();
    conn.close();
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 }
}

HttpSessionAttributeListener の例

次の単純な HttpSession イベントリスナの例では、HttpSessionAttributeListener のメソッドを実装します。これらのいずれかのイベントが発生すると、標準出力に行が出力されます。属性の値が変更されると、このイベントリスナはセッション属性のすべてを標準出力に出力します。

public final class SessionAttrLogger implements 
HttpSessionAttributeListener {
 public void attributeAdded(HttpSessionEvent event) {
  System.out.println("追加されたセッション属性");
 }
 public void attributeRemoved(HttpSessionEvent event) {
  System.out.println("削除されたセッション属性");
 }
 public void attributeReplaced(HttpSessionEvent event) {
  System.out.println("変更されたセッション属性");
  HttpSession session = event.getSession();
  Enumeration enum = session.getAttributeNames();
  while (enum.hasMoreElements()) {
   String attrname = (String)enum.nextElement();
   System.out.println(attrname + "=" + 
session.getAttribute(attrname));
  }
 }
}

HttpSessionActivationListener について

JRun は、セッションがアクティブになるかパッシベートされると、
HttpSessionActivationListener に通知します。

パッシベートは、JRun がセッションを無効にしないが、リソースを解放するためにセッションをディスクにバックアップした場合や、"ミラーリング" された JRun サーバに障害が発生し、別の JRun サーバがそのセッションを引き受けた場合に発生します。これは、セッションパーシスタンスとも呼ばれます。

アクティブ化は、セッションをパッシベートされたクライアントがリクエストし、セッションをディスクから取得するか、新規 JRun サーバにロードする必要がある場合に発生します。

次の単純な HttpSession イベントリスナの例では、HttpSessionActivationListener インターフェイスのメソッドを実装します。これらのいずれかのイベントが発生すると、標準出力に行が出力されます。

...
 public void sessionWillPassivate(HttpSessionEvent event) {
  System.out.println("Session was passivated");
 }
 public void sessionDidActivate(HttpSessionEvent event) {
  System.out.println("Session was activated");
 }
...