S-JIS[2010-01-14] 変更履歴

Javaサーブレット リスナー

サーブレットリスナーは、ウェブアプリケーションの各イベント毎に呼ばれるもの。
(サーブレット2.3以降)


リスナーの種類

イベントの対象 インターフェース
(使用方法)
メソッド 備考(呼ばれるタイミング)
サーブレットコンテキスト javax.servlet.
ServletContextListener
web.xmlに記述
contextInitialized() ウェブアプリの開始時。
フィルターサーブレットの初期化(init()呼び出し)より前。
contextDestroyed() ウェブアプリの終了時。
フィルターサーブレットのインスタンスの破棄(destroy()が呼ばれた)後。
javax.servlet.
ServletContextAttributeListener
web.xmlに記述
attributeAdded() ServletContext#setAttribute()によって初めて値がセットされた時。
attributeReplaced() ServletContext#setAttribute()によって既存の値が変更された時。
attributeRemoved() ServletContext#removeAttribute()によって値が削除された時。
無かった場合(既に削除されていた場合)は呼ばれない。
HTTPセッション javax.servlet.http.
HttpSessionListener
web.xmlに記述
sessionCreated() セッションが作られた時。
(request.getSession(true)が呼ばれた時とか)
sessionDestroyed() セッションが無効になる時。
(HttpSession#invalidate()が呼ばれた時やセッションタイムアウトした時)
2.3では無効になった後に呼ばれたが、2.4で無効になる前に呼ばれるよう変更になった。
javax.servlet.http
HttpSessionAttributeListener
web.xmlに記述
attributeAdded() HttpSession#setAttribute()によって初めて値がセットされた時。
attributeReplaced() HttpSession#setAttribute()によって既存の値が変更された時。
attributeRemoved() HttpSession#removeAttribute()によって値が削除された時。
無かった場合(既に削除されていた場合)は呼ばれない。
javax.servlet.http
HttpSessionActivationListener
(オブジェクトに実装)
sessionWillPassivate() セッションが非アクティブになる時(シリアライズされる前)。
APサーバー終了時にセッション情報がファイルに保存される際に呼ばれる。
(あるいはサーバーが分散されていて別サーバーに引き継がれる時)
sessionDidActivate() セッションがアクティブになった時(デシリアライズされた後)。
APサーバー起動時にセッション情報がファイルから復元された際に呼ばれる。
javax.servlet.http
HttpSessionBindingListener
(オブジェクトに実装)
valueBound() セッションにバインドされた時。
(HttpSession#setAttribute()によってセットされた時)
attributeAdded()の直前に呼ばれる)
valueUnbound() セッションからアンバインドされた時。
(HttpSession#removeAttribute()が呼ばれた時や、setAttribute()によって新しい値に置き換えられる時
あるいはセッションが破棄されたりタイムアウトした時)
attributeRemoved()attributeReplaced()の直前に呼ばれる)
サーブレットリクエスト javax.servlet.
ServletRequestListener
web.xmlに記述
requestInitialized() HTTPリクエストのオブジェクトが初期化された時。
(リクエストが来てからフィルターが実行される前)
requestDestroyed() HTTPリクエストのオブジェクトが破棄される時。
(一番外側のフィルターの呼び出しが終了した後)
javax.servlet.
ServletRequestAttributeListener
web.xmlに記述
attributeAdded() ServletRequest#setAttribute()によって初めて値がセットされた時。
attributeReplaced() ServletRequest#setAttribute()によって既存の値が変更された時。
attributeRemoved() ServletRequest#removeAttribute()によって値が削除された時。
無かった場合(既に削除されていた場合)は呼ばれない。

web.xmlに記述するリスナー

Swingのリスナーだと、addListener()系のメソッドを使ってリスナーインスタンスをコンポーネントに登録するが、)
サーブレット系のリスナー(のほとんど)はweb.xmlにクラス名を記述することによって、そのリスナーが呼ばれるようになる。

リスナーはインターフェースなので、それを実装した具象クラスを作り、web.xmlのlistener要素にそのクラス名を記述する。
すると、そのリスナーに該当するイベントが発生した際に、実装したメソッドが呼ばれる。

サーブレットコンテキストリスナーの例

SampleServletContextListener.java:

package jp.hishidama.sample.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class SampleServletContextListener implements ServletContextListener {

	@Override
	public void contextInitialized(ServletContextEvent sce) {
		print("contextInitialized", sce);
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		print("contextDestroyed", sce);
	}

	void print(String name, ServletContextEvent sce) {
		System.out.printf("■■" + this.getClass().getSimpleName() + "#" + name + "(%s)%n",
			sce.getServletContext().getServerInfo());
	}
}

web.xml

<?xml version="1.0" encoding="Shift_JIS" ?>
<web-app 〜>
〜
	<listener>
		<listener-class>jp.hishidama.sample.listener.SampleServletContextListener</listener-class>
	</listener>
〜
</web-app>

listener要素

listenerの要素(順序性あり)
要素 内容 備考 型定義
description * 2.4〜   descriptionGroup
順序性あり
javaee
display-name *
icon *
listener-class 1   リスナーのクラス名 FQCNで記述する。 javaee

listener要素はweb-app要素の下に複数書くことが出来る(複数のリスナークラスを登録できる)。
また、複数のリスナーインターフェースを1つのクラスに実装して、listener要素ではその実装クラスだけを書く、というやり方も可能。


マルチスレッドに注意

web.xmlで定義するリスナーは、サーブレットフィルターと同様に1インスタンスしか作られない。

ServletContextListenerに関しては(ウェブアプリの起動・終了時に呼ばれるものなので)たぶんマルチスレッドで呼ばれることは無いと思うが、
他のリスナーは複数スレッドから同時に呼ばれる可能性があるので、MTセーフ(スレッドセーフ)になるよう注意する必要がある。

サーブレット系全般の注意点


サーブレットへ戻る / JavaEEへ戻る / Java目次へ戻る
メールの送信先:ひしだま