Web基础知识(8)- Java Servlet (八) | Servlet Listener(监听器)
监听器 Listener 是一个实现特定接口的 Java 程序,这个程序专门用于监听另一个 Java 对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即自动执行。
1. 监听器的相关概念
事件:方法调用、属性改变、状态改变等。
事件源:被监听的对象( 例如:request、session、servletContext)。
监听器:用于监听事件源对象 ,事件源对象状态的变化都会触发监听器。
注册监听器:将监听器与事件源进行绑定。
2. 监听器的分类
Servlet 规范中定义了 8 个监听器接口,可以用于监听 ServletContext、HttpSession 和 ServletRequest 对象的生命周期和属性变化事件。开发 Servlet 监听器需要实现相应的监听器接口并重写接口中的方法。
监听器 Listener 按照监听的事件划分,可以分为 3 类:
(1) 监听对象创建和销毁的监听器
(2) 监听对象中属性变更的监听器
(3) 监听 HttpSession 中的对象状态改变的监听器
3. 监听对象创建和销毁的监听器
Servlet 规范定义了监听 ServletContext、HttpSession、HttpServletRequest 这三个对象创建和销毁事件的监听器,如下。
1) ServletContextListener 监听器
方法 | 描述 |
void contextInitialized (ServletContextEvent event) | 用于监听 ServletContext 对象的创建过程 |
void contextDestroyed (ServletContextEvent event) | 用于监听 ServletContext 对象的销毁过程 |
2) HttpSessionListener 监听器
方法 | 描述 |
void sessionCreated (HttpSessionEvent event) | 用于监听 HttpSession 对象的创建过程 |
void sessionDestroyed (HttpSessionEvent event) | 用于监听 HttpSession 对象的销毁过程 |
3) ServletRequestListener 监听器
方法 | 描述 |
void requestInitialized (ServletRequestEvent event) | 用于监听 ServletRequest 对象的创建过程 |
void requestDestroyed (ServletRequestEvent event) | 用于监听 ServletRequest 对象的销毁过程 |
4. 监听属性变更的监听器
Servlet 规范定义了监听 ServletContext、HttpSession、HttpServletRequest 这三个对象中的属性变更事件的监听器。如下。
1) ServletContextAttributeListener 监听器
方法 | 描述 |
void attributeAdded (ServletContextAttributeEvent event) | 用于监听 ServletContext 对象的属性新增 |
void attributeRemoved (ServletContextAttributeEvent event) | 用于监听 ServletContext 对象的属性移除 |
void attributeReplaced (ServletContextAttributeEvent event) | 用于监听 ServletContext 对象的属性替换 |
2) HttpSessionAttributeListener 监听器
方法 | 描述 |
void attributeAdded (HttpSessionBindingEvent event) | 用于监听 HttpSession 对象的属性新增 |
void attributeRemoved (HttpSessionBindingEvent event) | 用于监听 HttpSession 对象的属性移除 |
void attributeReplaced (HttpSessionBindingEvent event) | 用于监听 HttpSession 对象的属性替换 |
3) ServletRequestAttributeListener 监听器
方法 | 描述 |
void attributeAdded (ServletRequestAttributeEvent event) | 用于监听 HttpServletRequest 对象的属性新增 |
void attributeRemoved (ServletRequestAttributeEvent event) | 用于监听 HttpServletRequest 对象的属性移除 |
void attributeReplaced (ServletRequestAttributeEvent event) | 用于监听 HttpServletRequest 对象的属性替换 |
5. 监听 Session 中对象状态改变的监听器
Session 中的对象可以有多种状态:绑定到 Session 中、从 Session 中解除绑定、随 Session 对象持久化到存储设备中(钝化)、随 Session 对象从存储设备中恢复(活化)。
Servlet 规范中定义了两个特殊的监听器接口,用来帮助对象了解自己在 Session 中的状态:
HttpSessionBindingListener 接口和 HttpSessionActivationListener 接口 ,实现这两个接口的类不需要进行注册。
1) HttpSessionBindingListener 监听器
方法 | 描述 |
void valueBound (HttpSessionBindingEvent event) | 用于监听 JavaBean 对象绑定到 HttpSession 对象的事件 |
void valueUnbound (HttpSessionBindingEvent event) | 用于监听 JavaBean 对象从 HttpSession 对象解绑的事件 |
2) HttpSessionActivationListener 监听器
方法 | 描述 |
void sessionWillPassivate (HttpSessionBindingEvent event) | 用于监听 HttpSession 中对象活化的过程 |
void sessionDidActive (HttpSessionBindingEvent event) | 用于监听 HttpSession 中对象钝化的过程 |
6. 注册监听器
1) 在 web.xml 中注册监听器
在 web.xml 中使用 <listener> 标签配置监听器,Web 容器会自动把监听器注册到事件源中,示例代码如下。
<web-app>
<listener>
<listener-class>com.example.listener.TestListener</listener-class>
</listener>
</web-app>
2) 使用 @WebListener 注解注册监听器
在监听器类上使用 @WebListener 注解,可以将该 Java 类注册为一个监听器类。示例代码如下。
1 package com.example; 2 3 import javax.servlet.ServletContextEvent; 4 import javax.servlet.ServletContextListener; 5 import javax.servlet.annotation.WebListener; 6 7 @WebListener 8 public class TestListener implements ServletContextListener { 9 public TestListener() { 10 } 11 12 public void contextInitialized(ServletContextEvent servletContextEvent) { 13 } 14 15 public void contextDestroyed(ServletContextEvent servletContextEvent) { 16 } 17 18 }
示例:
1 // 监听对象创建和销毁的混合监听器 2 package com.example.listener; 3 4 import javax.servlet.ServletContextListener; 5 import javax.servlet.ServletRequestListener; 6 import javax.servlet.ServletContextEvent; 7 import javax.servlet.ServletRequestEvent; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpSessionEvent; 10 import javax.servlet.http.HttpSessionListener; 11 import javax.servlet.annotation.WebListener; 12 13 @WebListener("LifecycleMixListener") 14 public class LifecycleMixListener implements HttpSessionListener, 15 ServletContextListener, ServletRequestListener { 16 17 public void sessionCreated (HttpSessionEvent httpSessionEvent) { 18 System.out.println("LifecycleMixListener -> sessionCreated()"); 19 } 20 21 public void sessionDestroyed (HttpSessionEvent httpSessionEvent) { 22 System.out.println("LifecycleMixListener -> sessionDestroyed()"); 23 } 24 25 public void contextInitialized (ServletContextEvent servletContextEvent) { 26 System.out.println("LifecycleMixListener -> contextInitialized()"); 27 } 28 29 public void contextDestroyed (ServletContextEvent servletContextEvent) { 30 System.out.println("LifecycleMixListener -> contextDestroyed()"); 31 } 32 33 public void requestInitialized(ServletRequestEvent servletRequestEvent) { 34 HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest(); 35 System.out.println("LifecycleMixListener -> requestInitialized() : " + request.getRequestURI()); 36 } 37 38 public void requestDestroyed(ServletRequestEvent servletRequestEvent) { 39 HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest(); 40 System.out.println("LifecycleMixListener -> requestDestroyed() : " + request.getRequestURI()); 41 } 42 43 } 44 45 // 监听属性变更的混合监听器 46 package com.example.listener; 47 48 import javax.servlet.annotation.WebListener; 49 50 import javax.servlet.ServletContextAttributeEvent; 51 import javax.servlet.ServletContextAttributeListener; 52 import javax.servlet.ServletRequestAttributeEvent; 53 import javax.servlet.ServletRequestAttributeListener; 54 import javax.servlet.http.HttpSessionBindingEvent; 55 import javax.servlet.http.HttpSessionAttributeListener; 56 57 @WebListener("AttributeMixListener") 58 public class AttributeMixListener implements ServletContextAttributeListener, 59 HttpSessionAttributeListener, ServletRequestAttributeListener { 60 61 public void attributeAdded (ServletContextAttributeEvent servletContextAttributeEvent) { 62 System.out.println("AttributeMixListener -> attributeAdded(ServletContextAttributeEvent)"); 63 } 64 65 public void attributeRemoved (ServletContextAttributeEvent servletContextAttributeEvent) { 66 System.out.println("AttributeMixListener -> attributeRemoved(ServletContextAttributeEvent)"); 67 } 68 69 public void attributeReplaced (ServletContextAttributeEvent servletContextAttributeEvent) { 70 System.out.println("AttributeMixListener -> attributeReplaced(ServletContextAttributeEvent)"); 71 } 72 73 public void attributeAdded (ServletRequestAttributeEvent servletRequestAttributeEvent) { 74 System.out.println("AttributeMixListener -> attributeAdded(ServletRequestAttributeEvent)"); 75 } 76 77 public void attributeRemoved (ServletRequestAttributeEvent servletRequestAttributeEvent) { 78 System.out.println("AttributeMixListener -> attributeRemoved(ServletRequestAttributeEvent)"); 79 } 80 81 public void attributeReplaced (ServletRequestAttributeEvent servletRequestAttributeEvent) { 82 System.out.println("AttributeMixListener -> attributeReplaced(ServletRequestAttributeEvent)"); 83 } 84 85 public void attributeAdded (HttpSessionBindingEvent httpSessionBindingEvent) { 86 System.out.println("AttributeMixListener -> attributeAdded(HttpSessionBindingEvent)"); 87 } 88 89 public void attributeRemoved (HttpSessionBindingEvent httpSessionBindingEvent) { 90 System.out.println("AttributeMixListener -> attributeRemoved(HttpSessionBindingEvent)"); 91 } 92 93 public void attributeReplaced (HttpSessionBindingEvent httpSessionBindingEvent) { 94 System.out.println("AttributeMixListener -> attributeReplaced(HttpSessionBindingEvent)"); 95 } 96 } 97 98 // 监听 Session 中对象状态改变的监听器 99 package com.example.listener; 100 101 import javax.servlet.http.HttpSessionBindingEvent; 102 import javax.servlet.http.HttpSessionBindingListener; 103 import javax.servlet.http.HttpSessionActivationListener; 104 105 // 实现这两个接口的类不需要进行注册, 即不用在 web.xml 里配置,也不用使用 WebListener 注解 106 public class SessionMixListener implements HttpSessionBindingListener, HttpSessionActivationListener { 107 108 public void valueBound(HttpSessionBindingEvent event) { 109 System.out.println("SessionMixListener -> valueBound(HttpSessionBindingEvent)"); 110 } 111 112 public void valueUnbound(HttpSessionBindingEvent event) { 113 System.out.println("SessionMixListener -> valueUnbound(HttpSessionBindingEvent)"); 114 } 115 116 public void sessionWillPassivate(HttpSessionBindingEvent event) { 117 System.out.println("SessionMixListener -> sessionWillPassivate(HttpSessionBindingEvent)"); 118 } 119 120 public void sessionDidActive(HttpSessionBindingEvent event) { 121 System.out.println("SessionMixListener -> sessionDidActive(HttpSessionBindingEvent)"); 122 } 123 124 }