写在前面
这一部分学习监听器。Servlet API提供了一系列的事件和事件监听接口。上层的servlet/JSP应用能够通过调用这些API进行事件驱动的开发。 这里监听的所有事件都继承自java.util.Event对象。 监听器接口可以分为三类:ServletContext、 HttpSession 和ServletRequest 。
Servlet 3.0中出现的新监听器接口——javax.servlet.AsyncListener 将在后面的学习进行介绍。
监听器接口
监听器接口与相应的功能如下所示:
Listener | Functional |
---|---|
javax.servlet.ServletContextListener | 它能够响应ServletContext生命周期事件, 它提供了ServletContext创建之后和ServletContext关闭之前的会被调用的方法。 |
javax.servlet.ServletContextAttributeListener | 它能够响应ServletContext范围的属性添加、 删除、 替换事件。 |
javax.servlet.http.HttpSessionListener | 它能够响应HttpSession的创建、 超时和失效事件。 |
javax.servlet.http.HttpSessionAttributeListener | 它能响应HttpSession范围的属性添加、 删除、 替换事件。 |
javax.servlet.http.HttpSessionActivationListener | 它在一个HttpSession激活或者失效时被调用。 |
javax.servlet.http.HttpSessionBindingListener | 当有属性绑定或者解绑到HttpSession上时, |
HttpSessionBindingListener 监听器会被调用。|
|javax.servlet.ServletRequestListener| 它能够响应一个ServletRequest的创建或删除。|
|javax.servlet.ServletRequestAttributeListener| 它能响应ServletRequest范围的属性值添加、 删除、 修改事件。|
| javax.servlet.AsyncListener| 一个用于异步操作的监听器.|
总结一下:
- 监听器主要监听对象有:ServletContext、HttpSession与ServletRequset。
- 直接加上Listener,是监听对应对象的“生”和“死”。比如ServletContext的创建与关闭;HttpSession的创建、超时与失效;ServletRequest的创建与删除。
- 中间添加Attribute,然后加上Listener,是监听对应范围内的属性添加、删除、替换事件。范围有:ServletContext、HttpSession与ServletRequest。
- 除此之外的特殊监听接口有:HttpSessionActivationListener、HttpSessionBindingListener和AsyncListener。可以单独注意。
监听器的注册
编写一个监听器, 只需要写一个Java类来实现对应的监听器接口就可以了。类似Servlet类的实现。
在Servlet 3.0和Servlet 3.1中提供了两种注册监听器的方法。
1.使用WebListener注解:
@WebListener
public class ListenerClass implements ListenerInterface {
}
2.部署描述文档
在部署描述文档中增加一个listener元素。
</listener>
<listener-class>fully-qualified listener class</listener-class>
</listener>
可以在一个应用中添加多个监听器, 这些监听器是同步工作的。
下面将分别介绍各种监听器。
Servlet Context监听器
ServletContext的监听器接口有两个:ServletContextListener和ServletContextAttributeListener。
1.ServletContextListener
ServletContextListener能对ServletContext的创建和销毁做出响应。
当ServletContext初始化时, 容器会调用所有注册的ServletContextListeners的contextInitialized 方法。 该方法如下:
void contextInitialized(ServletContextEvent event)
当ServletContext将要销毁时, 容器会调用所有注册的ServletContextListeners的context Destroyed 方法。该方法如下:
void contextDestroyed(ServletContextEvent event)
contextInitialized 方法和contextDestroyed方法都会从容器获取到一个 ServletContextEvent。javax.servlet.ServletContextEvent是一个java.util.EventObject的子类 , 它定义了一个访问ServletContext的getServletContext 方法:
ServletContext getServletContext()
通过这个方法能够轻松地获取到ServletContext。
2.ServletContextAttributeListener
当一个ServletContext范围的属性被添加、 删除或者替换时, ServletContextAttributeListener接口的实现会接收到消息。 这个接口定义了如下三个方法:
//添加
void attributeAdded(ServletContextAttributeEvent event)
//删除
void attributeRemoved(ServletContextAttributeEvent event)
//替换
void attributeReplaced(ServletContextAttributeEvent event)
- attributeAdded方法在一个ServletContext范围属性被添加时被容器调用。
- attributeRemoved方法在一个ServletContext范围属性被删除时被容器调用。
- attributeReplaced方法在一个ServletContext范围属性被新的替换时被容器调用。
这三个方法都能获取到一ServletContextAttributeEvent的对象, 通过这个对象以获取属性的名称和值。ServletContextAttributeEvent类继承自ServletContextAttribute, 并且增加了下面两个方法分别用于获取该属性的名称和值:
java.lang.String getName()
java.lang.Object getValue()
HttpSession Listener
一共有四个HttpSession相关的监听器接口:HttpSessionListener,HttpSessionActivation Listener、HttpSessionAttributeListener和HttpSessionBindingListener。 这四个接口都在javax.servlet.http包中。
1.HttpSessionListener
当一个HttpSession创建或者销毁时, 容器都会通知所有的HttpSessionListener监听器, HttpSessionListener接口有两个方法: sessionCreatedsessionDestroyed:
void sessionCreated(HttpSessionEvent event)
void sessionDestroyed(HttpSessionEvent event)
这两个方法都可以接收到一个继承于java.util.Event
的HttpSessionEvent对象。 可以通过调用HttpSessionEvent对象的getSession方法来获取当前的HttpSession。 getSession方法如下:
HttpSession getSession()
2.HeepSessionAttributeListener
HttpSessionAttributeListener接口和ServletContextAttributeListener类似, 它响应的是HttpSession范围属性的添加、 删除和替换。
HttpSessionAttributeListener接口有以下方法:
//添加
void attributeAdded(HttpSessionBindingEvent event)
//删除
void attributeRemoved( HttpSessionBindingEvent event)
//替换
void attributeReplaced( HttpSessionBindingEvent event)
- attributeAdded方法在一个HttpSession范围属性被添加时被容器调用。
- attributeRemoved方法在一个HttpSession范围属性被删除时被容器调用。
- attributeReplaced方法在一个HttpSession范围属性被新的替换时被容器调用。
这三个方法都能获取到一个HttpSessionBindingEvent 的对象, 通过这个对象可以获取属性的名称和值:
java.lang.String getName()
java.lang.Object getValue()
由于HttpSessionBindingEvent是HttpSessionEvent的子类, 因此也可以在HttpSession Attribute Listener 实现类中获得HttpSession。
3.HttpSessionActivationListener
在分布式环境下, 会用多个容器来进行负载均衡,有可能需要将session保存起来, 在容器之间传递。例如当一个容器内存不足时, 会把很少用到的对象转存到其他容器上。 这时候, 容器就会通知所有HttpSessionActivationListener 接口的实现类。
HttpSessionActivationListener接口有两个方法,sessionDidActivate和sessionWillPassivate:
void sessionDidActivate(HttpSessionEvent event)void sessionWillPassivate(HttpSessionEvent event)
- 当HttpSession被转移到其他容器之后,sessionDidActivate方法会被调用。 容器将一个HttpSessionEvent方法传递到方法里, 可以从这个对象获得HttpSession。
- 当一个HttpSession将要失效时, 容器会调用sessionWillPassivate方法。 和sessionDidActivate方一样, 容器将一个HttpSessionEvent方法传递到方法里,可以从这个对象获得HttpSession。
4.HttpSessionBindingListener
当有属性绑定或者解绑到HttpSession上时,HttpSessionBindingListener 监听器会被调用。 如果对HttpSession属性的绑定和解绑动作感兴趣, 就可以实现HttpSessionBindingListener 来监听。 例如可以在HttpSession属性绑定时更新状态, 或者在属性解绑释放资源。
ServletRequest Listeners
ServletRequest范围的监听器接口有三个:ServletRequestListener、 ServletRequestAttributeListener和AsyncListener。
1.ServletRequestListener
ServletRequestListener监听器会对ServletRequest的创建和销毁事件进行响应。 容器会通过一个池来存放并重复利用多个ServletRequest, ServletRequest的创是从容器池里被分配出来的时刻开始, 而它的销毁时刻是放回容器池里的时间。
ServletRequestListener 接口有两个方法,requestInitialized和requestDestroyed:
void requestInitialized(ServletRequestEvent event)
void requestDestroyed(ServletRequestEvent event)
- 一个ServletRequest创建(从容器池里取出)时, requestInitialized方法会被调用;
- ServletRequest销毁(被容器回收) 时, requestDestroyed方法会被调用。
这两个方法都会接收到一个ServletRequestEvent对象,可以通过使用这个对象的getServletRequest方法来获取ServletRequest对象:
ServletRequest getServletRequest()
另外, ServletRequestEvent接口也提供了一个getServletContext方法来获取ServletContext, 如下所示:
ServletContext getServletContext()
1.ServletRequestAttributeListener
当一个ServletRequest范围的属性被添加、 删除或替换时, ServletRequestAttributeListener接口会被调用。ServletRequestAttributeListener接口提供了三个方法:attributeAdded、 attribute ReplacedattributeRemoved。
//添加
void attributeAdded(ServletRequestAttributeEvent event)
//删除
void attributeRemoved(ServletRequestAttributeEvent event)
//替换
void attributeReplaced(ServletRequestAttributeEvent event)
这些方法都可以获得一个继承自ServletRequestEvent的ServletRequestAttributeEvent对象。 通过ServletRequestAttributeEvent类提供getName和getValue方法可以访问到属性的名称和值:
java.lang.String getName()
java.lang.Object getValue()
写在后面
Servlet API提供的多个监听器类型。 这些监听器可以分成三类: application范围、session范围和request范围。 监听器的使用很简单, 可以通过两种方式注册监听器: 在实现类上使用@WebListener注解或者在部署描述文件中增加listener元素。
本系列学习都是书籍《Servlet JSP和Spring MVC初学指南》中内容,主要是自己学习内容的一个整理,仅供学习交流之用。