建立監聽器的監聽器接口屬于javax.servlet和javax.servlet.http包的一部分,詳情如下:
javax.servlet.servletcontextlistener。這是對servlet context生命周期事件做出響應的監聽器。建立好servlet context時會馬上調用它的一個方法,并在關閉servlet context之前調用它的另一個方法。
javax.servlet.servletcontextattributelistener。這是在添加、删除或替換某個servlet context屬性時采取相應動作的監聽器。
javax.servlet.http.httpsessionattributelistener。這是在建立、移除或替換servlet上下文屬性時響應的監聽器。
javax.servlet.http.httpsessionattributelistener。這是在添加、删除或替換某個session屬性時被調用的監聽器。
javax.servlet.httpsessionactivationlistener。這是在打開和關閉某個httpsession時被調用的監聽器。
javax.servlet.http.httpsessionbindinglistener。這是一個類,其執行個體将被儲存為可以實作這個接口的httpsession屬性。當它在httpsession中被添加或者删除時,實作httpsessionbindinglistener的類執行個體會收到通知。
javax.servlet.servletrequestlistener。這是對servletrequest的建立和删除做出響應的監聽器。
javax.servlet.servletrequestattributelistener。當servletrequest中添加、删除或替換掉某個屬性時,會調用該監聽器的方法。
javax.servlet.asynclistener。用于異步操作的監聽器。
1、注解
@weblistener
public class listenerclass implements listenerinterface{
}
2、配置檔案
<listener>
<listener-class>fully-qualified listener class</listener-class>
</listener>
在應用程式中可以想要多少個監聽器就可以有多少個監聽器。注意,對監聽器方法的調用是同步進行的。
在servletcontext級别上有兩個監聽器接口:servletcontextlistener和servletcontextattributelistener。
servletcontextlistener會對servletcontext的初始化和解構做出響應。servletcontext被初始化時,servlet容器會在所有已注冊的servletcontextlistener中調用contextinitialized方法,其方法簽名如下:
void contextinitialized(servletcontextevent event)
當servletcontext要被解構和銷毀時,servlet容器會在所有已注冊的servletcontextlistener中調用contextdestroyed方法,以下是contextdestroyed的方法簽名:
void contextdestroyed(servletcontextevent event)
contentinitialized和contextdestroyed都會收到一個來自servlet容器的servletcontextevent。java.util.eventobject類的一個派生類:javax.servlet.servletcontextevent。定義了一個傳回servletcontext的getservletcontext方法:
servletcontext getservletcontext()
這個方法很重要,因為這是方位servletcontext的唯一簡便方法。它有許多servletcontextlistener,可以将屬性儲存在servletcontext中。
下面是個例子:
countries.jsp
<%@ page language="java" import="java.util.*" pageencoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>my jsp 'countries.jsp' starting page</title>
</head>
<body>
we operate in these countries:
<ul>
<c:foreach items="${countries}" var="country">
<li>${country.value}</li>
</c:foreach>
</ul>
</body>
</html>
applistener.java
package app08a.listener;
import java.util.hashmap;
import java.util.map;
import javax.servlet.servletcontext;
import javax.servlet.servletcontextevent;
import javax.servlet.servletcontextlistener;
import javax.servlet.annotation.weblistener;
@weblistener
public class applistener implements servletcontextlistener{
@override
public void contextdestroyed(servletcontextevent sce) {
}
public void contextinitialized(servletcontextevent sce) {
system.out.println("servletcontextlistener started");
servletcontext servletcontext = sce.getservletcontext() ;
map<string,string> countries = new hashmap<string,string>() ;
countries.put("ca", "canada") ;
countries.put("us", "united states") ;
servletcontext.setattribute("countries", countries) ;
}
每當servletcontext中添加、删除或替換了某個屬性時,servletcontextattributelistener的實作都會收到通知。下面就是監聽器中定義的三個方法。
void attributeadded(servletcontextattributeevent event)
void attributeremoved(servletcontextattributeevent event)
void attributereplaced(servletcontextattributeevent event)
每當servletcontext中添加了某個屬性時,servlet容器就會調用attributeadded方法。每當servletcontext中删除了某個屬性時,則是調用attributeremoved方法。每當servletcontext被新的替代時,則是調用attributereplaced方法。
servletcontextattributeevent類派生于servletcontextattribute,并添加了下面這兩個方法,分别用來擷取屬性名稱和屬性值。
java.lang.string getname()
java.lang.object.getvalue()
與httpsession有關的監聽器接口有4個:httpsessionlistener、httpsessionactivationlistener、httpsessionattributelistener和httpsessionbindinglistener。
當有httpsession被建立或者銷毀時,servlet容器就會調用所有已注冊的httpsessionlistener。httpsessionlistener中定義的兩個方法是sessioncreated和sessiondestroyed
void sessioncreated(httpsessionevent event)
void sessiondestroyed(httpsessionevent event)
這兩個方法都收到一個httpsessionevent執行個體,它是java.util.event的派生類。我們可以在httpsessionevent中調用getsession方法以獲得所建立或銷毀的httpsession,getsession方法簽名如下:
httpsession getsession()
下面是一個計數器的例子:
sessionlistener.java
import java.util.concurrent.atomic.atomicinteger;
import javax.servlet.http.httpsession;
import javax.servlet.http.httpsessionevent;
import javax.servlet.http.httpsessionlistener;
public class sessionlistener implements httpsessionlistener,servletcontextlistener{
servletcontext.setattribute("usercontroller", new atomicinteger());
public void sessioncreated(httpsessionevent se) {
httpsession session = se.getsession() ;
servletcontext servletcontext = session.getservletcontext() ;
atomicinteger usercounter = (atomicinteger)servletcontext.getattribute("usercontroller") ;
int usercount = usercounter.incrementandget() ;
system.out.println("usercount increment to :" + usercount);
public void sessiondestroyed(httpsessionevent se) {
int usercount = usercounter.decrementandget() ;
system.out.println("usercount decrement to :" + usercount);
對剛才的jsp進行測試,控制台輸出如下:
usercount increment to :1
如果你換個浏覽器運作,或者等到session過期,你會發現控制台輸出如下:
usercount increment to :2
下面是方法:
void attributeadded(httpsessionbindingevent event)
void attributeremoved(httpsessionbindingevent event)
void attributereplaced(httpsessionbindingevent event)
所有的監聽器方法都會收到一個httpsessionbindingevent執行個體,你可以從中獲得相應的httpsession和屬性值及名稱。
java.lang.object getvalue()
在分布式環境中,多個servlet容器會配置成可伸縮的,為了節省記憶體,servlet容器可以對session屬性進行遷移或者序列化。一般來說,當記憶體比較低時,相對較少通路的對象可以序列化到備用儲存設備中,這樣,servlet容器就能夠注意到哪些session屬性的類實作了httpsessionactivationlistener接口。
這個接口中定義了兩個方法:sessiondisactivate和sessionwillpassivate
void sessiondisactivate(httpsessionevent event)
void sessionwillpassivate(httpsessionevent event)
當httpsessionbindinglistener綁定到httpsession,或者取消綁定時,都會收到通知。如果一個類想要知道什麼時候綁定或取消綁定到httpsession上,那麼這個類要實作httpsessionbindinglistener接口,然後将它的執行個體儲存為session屬性。例如,有個對象的類實作了這個接口,當它儲存為httpsession屬性時,它就可以自動更新。再比如,一但httpsessionbindinglistener與httpsession取消綁定,它的實作就可以釋放占用的資源。
package app08a.model;
import javax.servlet.http.httpsessionbindingevent;
import javax.servlet.http.httpsessionbindinglistener;
public class product implements httpsessionbindinglistener{
private string id ;
private string name ;
private double price ;
public string getid() {
return id;
public void setid(string id) {
this.id = id;
public string getname() {
return name;
public void setname(string name) {
this.name = name;
public double getprice() {
return price;
public void setprice(double price) {
this.price = price;
public void valuebound(httpsessionbindingevent event) {
string attributename = event.getname() ;
system.out.println(attributename + " valuebound");
public void valueunbound(httpsessionbindingevent event) {
system.out.println(attributename + " valueunbound");
當監聽器與httpsession綁定或者取消綁定時,它索要做的隻是将内容輸出到控制台即可。
在servletrequest級别上有3個監聽器接口:servletrequestlistener、servletrequestattributelistener和asynclistener。
servletrequestlistener對servletrequest的建立和銷毀做出響應。在servlet容器中是通過池來重用servletrequest的,建立servletrequest花費的時間相當于從池中擷取它的時間,servletrequest銷毀時間則相當于它傳回到池中的時間。
servletrequestlistener接口定義了兩個方法:簽名如下:
void requestinitialized(servletrequestevent event)
void requestdestroyed(servletrequestevent event)
建立servletrequest時會調用requestinitialized方法,servletrequest被銷毀時會調用requestdestroyed方法。這兩個方法都會收到一個servletrequestevent,通過調用getservletrequest方法,可以從中擷取到響應的servletrequest執行個體
servletrequest getservletrequest()
此外,servletrequestevent接口還定義了傳回servletcontext的getservletcontext方法,簽名如下:
下面的這個例子是計算servletrequest建立到銷毀之間的時間差,進而準确得出執行請求所花費的時間。
import javax.servlet.servletrequest;
import javax.servlet.servletrequestevent;
import javax.servlet.servletrequestlistener;
import javax.servlet.http.httpservletrequest;
public class perfstatlistener implements servletrequestlistener{
public void requestdestroyed(servletrequestevent sre) {
// todo auto-generated method stub
servletrequest servletrequest = sre.getservletrequest() ;
long start = (long)servletrequest.getattribute("start") ;
long end = system.nanotime() ;
httpservletrequest httpservletrequest = (httpservletrequest)servletrequest ;
string uri = httpservletrequest.getrequesturi() ;
system.out.println("time taken to execute " + uri + ":" + ((end-start)/100) + "microseconds");
public void requestinitialized(servletrequestevent sre) {
servletrequest.setattribute("start", system.nanotime());
nanotime方法傳回一個表示任意時間的long。這個傳回值與任何系統概念或者壁鐘的時間無關,但是在同一台jvm中得到的兩個傳回值,最适合用來計算第一個nanotimes調用和第二個調用之間過了多長時間。
但在servletrequest中添加、删除或者替換某個屬性時,會調用servletrequestattributelistener。servletrequestattributelistener接口中定義了3個方法:attributeadded、attributereplaced和attributeremoved,定義如下:
void attributeadded(servletrequestattributeevent event)
void attributereplaced(servletrequestattributeevent event)
void attributeremoved(servletrequestattributeevent event)
所有方法都會收到一個servletrequestattributeevent 執行個體。servletrequestattributeevent 類通過getname和getvalue方法暴露有關的屬性: