摘要:本文学习了Listener的原理和使用方法。
环境
Windows 10 企业版 LTSC 21H2
Java 1.8
Tomcat 8.5.50
1 简介
Listener用于监听JavaWeb程序中的事件,并在监听事件触发时执行相应的操作。
Listener是JavaWeb三大组件之一。
2 原理
Listener基于观察者模式,所谓观察者模式,就是当被观察的特定事件触发后,会通过调用观察者的方法通知观察者,观察者可以在方法中对事件做一些处理。
在JavaWeb中,被观察的对象有三个:
- ServletRequest:对应请求的生命周期事件。
- HttpSession:对应会话的生命周期事件。
- ServletContext:对应应用程序的生命周期事件。
3 分类
对象生命周期监听器:
- ServletRequestListener:监听ServletRequest对象的创建和销毁。
- HttpSessionListener:监听HttpSession对象的创建和销毁。
- ServletContextListener:监听ServletContext对象的创建和销毁。
属性变化监听器:
- ServletRequestAttributeListener:监听ServletRequest域中属性的变化。
- HttpSessionAttributeListener:监听HttpSession域中属性的变化。
- ServletContextAttributeListener:监听ServletContext域中属性的变化。
特殊会话监听器:
- HttpSessionActivationListener:监听Session中对象的活化和钝化。
- HttpSessionBindingListener:监听Session中对象的绑定和解绑。
4 注册
实现监听器接口后,还需要注册监听器才能生效,注册方式有两种:
- 通过配置文件注册,在web.xml中配置监听器:
web.xml1 2 3
| <listener> <listener-class>com.example.listener.XxxListener</listener-class> </listener>
|
- 通过注解注册,使用
@WebListener注解:java1 2 3 4
| @WebListener public class XxxListener implements XxxListener { ... }
|
特殊会话监听器不需要创建监听器和注册监听器,但是需要被监听的Bean实现监听接口。
5 使用
5.1 对象生命周期监听器
5.1.1 ServletRequestListener
ServletRequestListener监听器用于监听HttpServletRequest对象的创建和销毁事件。
ServletRequest对象在请求到达时创建,在响应结束时销毁。
监听方法:
java1 2 3 4 5 6 7 8 9 10 11 12 13
| @WebListener public class TestServletRequestListener implements ServletRequestListener { @Override public void requestInitialized(ServletRequestEvent event) { System.out.println("ServletRequest对象被创建了"); } @Override public void requestDestroyed(ServletRequestEvent event) { System.out.println("ServletRequest对象被销毁了"); } }
|
5.1.2 HttpSessionListener
HttpSessionListener监听器用于监听HttpSession对象的创建和销毁事件。
HttpSession对象在首次调用getSession()方法时创建,在最后调用invalidate()方法时销毁。
监听方法:
java1 2 3 4 5 6 7 8 9 10 11 12 13
| @WebListener public class TestHttpSessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent event) { System.out.println("HttpSession对象被创建了"); } @Override public void sessionDestroyed(HttpSessionEvent event) { System.out.println("HttpSession对象被销毁了"); } }
|
5.1.3 ServletContextListener
ServletContextListener监听器用于监听ServletContext对象的创建和销毁事件。
ServletContext对象在Web应用启动时创建,在Web应用停止时销毁。
监听方法:
java1 2 3 4 5 6 7 8 9 10 11 12 13
| @WebListener public class TestServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent event) { System.out.println("ServletContext对象被创建了"); } @Override public void contextDestroyed(ServletContextEvent event) { System.out.println("ServletContext对象被销毁了"); } }
|
5.2 属性变化监听器
5.2.1 ServletRequestAttributeListener
ServletRequestAttributeListener监听器用于监听ServletRequest域中属性的变化事件。
监听方法:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @WebListener public class TestServletRequestAttributeListener implements ServletRequestAttributeListener { @Override public void attributeAdded(ServletRequestAttributeEvent event) { System.out.println("ServletRequest域中添加了属性:" + event.getName()); } @Override public void attributeRemoved(ServletRequestAttributeEvent event) { System.out.println("ServletRequest域中移除了属性:" + event.getName()); } @Override public void attributeReplaced(ServletRequestAttributeEvent event) { System.out.println("ServletRequest域中替换了属性:" + event.getName()); } }
|
5.2.2 HttpSessionAttributeListener
HttpSessionAttributeListener监听器用于监听HttpSession域中属性的变化事件。
监听方法:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @WebListener public class TestHttpSessionAttributeListener implements HttpSessionAttributeListener { @Override public void attributeAdded(HttpSessionBindingEvent event) { System.out.println("HttpSession域中添加了属性:" + event.getName()); } @Override public void attributeRemoved(HttpSessionBindingEvent event) { System.out.println("HttpSession域中移除了属性:" + event.getName()); } @Override public void attributeReplaced(HttpSessionBindingEvent event) { System.out.println("HttpSession域中替换了属性:" + event.getName()); } }
|
5.2.3 ServletContextAttributeListener
ServletContextAttributeListener监听器用于监听ServletContext域中属性的变化事件。
监听方法:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @WebListener public class TestServletContextAttributeListener implements ServletContextAttributeListener { @Override public void attributeAdded(ServletContextAttributeEvent event) { System.out.println("ServletContext域中添加了属性:" + event.getName()); } @Override public void attributeRemoved(ServletContextAttributeEvent event) { System.out.println("ServletContext域中移除了属性:" + event.getName()); } @Override public void attributeReplaced(ServletContextAttributeEvent event) { System.out.println("ServletContext域中替换了属性:" + event.getName()); } }
|
5.3 特殊会话监听器
5.3.1 HttpSessionActivationListener
HttpSessionActivationListener监听器用于监听Session中对象的活化和钝化。
概念:
- 钝化(Passivate):将会话对象从内存序列化到磁盘。
- 活化(Activate):将会话对象从磁盘反序列化到内存。
监听方法,不需要注册,但是需要被监听的Bean实现序列化接口和监听接口:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public class Student implements Serializable, HttpSessionActivationListener { private String name;
public Student() { }
public Student(String name) { this.name = name; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Override public String toString() { return "Student{" + "name='" + name + '\'' + '}'; }
@Override public void sessionWillPassivate(HttpSessionEvent event) { System.out.println("Student对象即将钝化"); }
@Override public void sessionDidActivate(HttpSessionEvent event) { System.out.println("Student对象已经活化"); } }
|
5.3.2 HttpSessionBindingListener
HttpSessionBindingListener监听器用于监听Session中对象的绑定和解绑。
监听方法,不需要注册,但是需要被监听的Bean实现监听接口:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public class Student implements HttpSessionBindingListener { private String name;
public Student() { }
public Student(String name) { this.name = name; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Override public String toString() { return "Student{" + "name='" + name + '\'' + '}'; }
@Override public void valueBound(HttpSessionBindingEvent event) { System.out.println("Session绑定了Student对象:" + event.getName()); }
@Override public void valueUnbound(HttpSessionBindingEvent event) { System.out.println("Session解绑了Student对象:" + event.getName()); } }
|
条