抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

摘要:本文学习了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.xml
    1
    2
    3
    <listener>
    <listener-class>com.example.listener.XxxListener</listener-class>
    </listener>
  • 通过注解注册,使用@WebListener注解:
    java
    1
    2
    3
    4
    @WebListener
    public class XxxListener implements XxxListener {
    ...
    }

特殊会话监听器不需要创建监听器和注册监听器,但是需要被监听的Bean实现监听接口。

5 使用

5.1 对象生命周期监听器

5.1.1 ServletRequestListener

ServletRequestListener监听器用于监听HttpServletRequest对象的创建和销毁事件。

ServletRequest对象在请求到达时创建,在响应结束时销毁。

监听方法:

java
1
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()方法时销毁。

监听方法:

java
1
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应用停止时销毁。

监听方法:

java
1
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域中属性的变化事件。

监听方法:

java
1
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域中属性的变化事件。

监听方法:

java
1
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域中属性的变化事件。

监听方法:

java
1
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实现序列化接口和监听接口:

java
1
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实现监听接口:

java
1
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());
}
}

评论