8.2. セッションへのオブジェクトの登録/置換/削除を検知する
セッションへのオブジェクトの登録/置換/削除を検知する手段も提供されています。これには2つあって、「javax.servlet.http.HttpSessionAttributeListener」を用いる方法と、「javax.servlet.http.HttpSessionBindingListener」を用いる方法とがあります。まずHttpSessionAttributeListenerを用いる方法について説明します。
このリスナーはServletContextAttributeListenerに非常に良く似ています。以下の3つのメソッドを提供しており、それぞれ「オブジェクトが登録されたとき」「置き換えられたとき」「削除されたとき」に呼ばれます。ServletContextAttributeListenerとの違いは、引数の型だけだと言えるでしょう。
// セッションにオブジェクトが登録されたときに呼ばれるメソッド void attributeAdded(HttpSessionBindingEvent event) // セッションのオブジェクトが置き換えられたときに呼ばれるメソッド void attributeReplaced(HttpSessionBindingEvent event) // セッションのオブジェクトが削除されたときに呼ばれるメソッド void attributeRemoved(HttpSessionBindingEvent)
HttpSessionBindingEventはセッションと登録/置換/削除されたオブジェクトを管理するイベントオブジェクトで、以下の3つのメソッドを提供しています。
// イベントが発生したセッションを返す HttpSession getSession() // 登録/置換/削除されたオブジェクトが関連付けられている名前を返す String getName() // 登録/置換/削除されたオブジェクトを返す // 置換の場合は、置換された古いオブジェクトを返します Object getValue()
以下はHttpSessionAttributeListenerの例です。あるオブジェクトが登録されると別のオブジェクトも登録、削除されると別のオブジェクトも削除しています。
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSession;
public class ObjectBindingListener implements HttpSessionAttributeListener{
public void attributeAdded(HttpSessionBindingEvent event){
HttpSession session=event.getSession();
if(event.getValue() instanceof Sample1){
// 別のオブジェクトも登録
session.setAttribute("sample2",new Sample2());
...
}
}
public void attributeReplaced(HttpSessionBindingEvent event){
HttpSession session=event.getSession();
if(event.getValue() instanceof Sample1){
// 別のオブジェクトも登録し直し
session.setAttribute("sample2",new Sample2());
...
}
}
public void attributeRemoved(HttpSessionBindingEvent event){
HttpSession session=event.getSession();
if(event.getValue() instanceof Sample1){
// 別のオブジェクトも削除
session.removeAttribute("sample2");
}
}
}
このリスナーを動作させるためには設定が必要です。他と同じく、web.xmlで<listener>タグを用いて設定を行います。
続いてHttpSessionBindingListenerについて説明します。このリスナーは他と違って、セッションに登録されるオブジェクトに実装します。定義されているメソッドは以下の2つです。
// セッションに登録されたときに呼ばれるメソッド void valueBound(HttpSessionBindingEvent event) // セッションから削除されたときに呼ばれるメソッド void valudUnbound(HttpSessionBindingEvent event)
以下はHttpSessionBindingListenerを実装しているオブジェクトの例です。
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.ServletContext;
public class BoundObject implements HttpSessionBindingListener{
private String[] array=null;
...
public void valueBound(HttpSessionBindingEvent event){
// セッション登録時の初期化処理を行う
ServletContext context=event.getSession().getServletContext();
array=new String[5];
array[0]=context.getInitParameter("...");
...
}
public void valueUnbound(HttpSessionBindingEvent event){
// セッション削除時の終了処理を行う
ServletContext context=event.getSession().getServletContext();
if(!array[0].equals.getInitParameter("...")){
...
}
}
}
このリスナーを動作させるのに特別な設定は必要ありません。サーブレットコンテナは、セッションに登録/削除されるオブジェクトがHttpSessionBindingListenerを実装している場合、それのvalueBound/valueUnboundメソッドを呼び出すようになっています。
HttpSessionAttributeListenerとHttpSessionBindingListenerは、オブジェクトがセッションに登録/置換/削除されるタイミングで何らかの処理を行いたい場合に、使用するのが適切です。オブジェクトが登録されるときにDBにロックをかけ、削除されるときに解除するというような事が考えられます。実装はHttpSessionBindingListenerが解りやすいのに対して、HttpSessionAttributeListenerはリスナーの取り外しが楽という利点があります。複数のオブジェクトを1つのリスナーで扱えるという利点もあります。場合に応じて使い分けるのが良いでしょう。
(実習課題2)
任意のWebアプリケーションに、以下のリスナーを追加しなさい。
- HttpSessionに登録/置換/削除されるオブジェクトを検知し、ログとして出力すること。
- 処理が行われた時刻、セッションのIDおよびオブジェクトのクラス名がログとして出力されるようにすること。

