8.1、监听器接口和注册
创建监听器的监听器接口属于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。用于异步操作的监听器。
创建监听器时,只要创建一个实现相关接口的Java类即可。在Servlet 3.0中。注册监听器有两种方法。
1、注解
@WebListener
public class ListenerClass implements ListenerInterface{
}
2、配置文件
<listener>
<listener-class>fully-qualified listener class</listener-class>
</listener>
在应用程序中可以想要多少个监听器就可以有多少个监听器。注意,对监听器方法的调用是同步进行的。
8.2、ServletContext监听器
在ServletContext级别上有两个监听器接口:ServletContextListener和ServletContextAttributeListener。
8.2.1、ServletContextListener
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
AppListener.java
8.2.2、ServletContextAttributeListener
每当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()
8.3、Session监听器
与HttpSession有关的监听器接口有4个:HttpSessionListener、HttpSessionActivationListener、HttpSessionAttributeListener和HttpSessionBindingListener。
8.3.1、HttpSessionListener
当有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
countries.jsp
对刚才的jsp进行测试,控制台输出如下:
userCount increment to :1
如果你换个浏览器运行,或者等到session过期,你会发现控制台输出如下:
userCount increment to :1
userCount increment to :2
8.3.2、HttpSessionAttributeListener
下面是方法:
void attributeAdded(HttpSessionBindingEvent event)
void attributeRemoved(HttpSessionBindingEvent event)
void attributeReplaced(HttpSessionBindingEvent event)
所有的监听器方法都会收到一个HttpSessionBindingEvent实例,你可以从中获得相应的HttpSession和属性值及名称。
java.lang.String getName()
java.lang.Object getValue()
8.3.3、HttpSessionActivationListener
在分布式环境中,多个Servlet容器会配置成可伸缩的,为了节省内存,Servlet容器可以对session属性进行迁移或者序列化。一般来说,当内存比较低时,相对较少访问的对象可以序列化到备用存储设备中,这样,Servlet容器就能够注意到哪些session属性的类实现了HttpSessionActivationListener接口。
这个接口中定义了两个方法:sessionDisActivate和sessionWillPassivate
void sessionDisActivate(HttpSessionEvent event)
void sessionWillPassivate(HttpSessionEvent event)
8.3.4、HttpSessionBindingListener
当HttpSessionBindingListener绑定到HttpSession,或者取消绑定时,都会收到通知。如果一个类想要知道什么时候绑定或取消绑定到HttpSession上,那么这个类要实现HttpSessionBindingListener接口,然后将它的实例保存为session属性。例如,有个对象的类实现了这个接口,当它保存为HttpSession属性时,它就可以自动更新。再比如,一但HttpSessionBindingListener与HttpSession取消绑定,它的实现就可以释放占用的资源。
8.4、ServletRequest监听器
在ServletRequest级别上有3个监听器接口:ServletRequestListener、ServletRequestAttributeListener和AsyncListener。
8.4.1、ServletRequestListener
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方法,签名如下:
ServletContext getServletContext()
下面的这个例子是计算ServletRequest创建到销毁之间的时间差,从而准确得出执行请求所花费的时间。
nanoTime方法返回一个表示任意时间的long。这个返回值与任何系统概念或者壁钟的时间无关,但是在同一台JVM中得到的两个返回值,最适合用来计算第一个nanoTimes调用和第二个调用之间过了多长时间。
8.4.2、ServletRequestAttributeListener
但在ServletRequest中添加、删除或者替换某个属性时,会调用ServletRequestAttributeListener。ServletRequestAttributeListener接口中定义了3个方法:attributeAdded、attributeReplaced和attributeRemoved,定义如下:
void attributeAdded(ServletRequestAttributeEvent event)
void attributeReplaced(ServletRequestAttributeEvent event)
void attributeRemoved(ServletRequestAttributeEvent event)
所有方法都会收到一个ServletRequestAttributeEvent 实例。ServletRequestAttributeEvent 类通过getName和getValue方法暴露有关的属性:
java.lang.String getName()
java.lang.Object getValue()