创建监听器的监听器接口属于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方法暴露有关的属性: