监听器

概述

1、一组来自于 Servlet 规范下接口,共有8个接口。在 Tomcat 存在 Servlet-api.jar 包。
2、监听器接口需要由开发人员亲自实现,Http 服务器提供 jar 包并没有对应的实现类。
3、监听器接口用于监控【作用域对象生命周期变化时刻】以及【作用域对象共享数据变化时刻】。
4、 Servlet 监听器主要是用来监听特定对象的创建或销毁、属性的变化而实现特定接口普通Java程序。监听器专门用于监听一个 Java 对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。 Listener 用于监听 Java Web 程序中的事件,例如创建、修改、删除 session 、 request 、 context 等,并触发响应的事件。
5、简单地说,被监听对象 A 中,关联着 B 对象。事件源 A 类对外提供一个方法,用于设置监听器对象B到A类的某一实例变量中。在需要监听事件源的方法中,方法体的某处先构造创建一个 Event 对象,将 this 即 B 与相关的动作封装进 Event 对象中,然后调用监听器 B 对象的事件方法,将事件对象传入方法实参中。

作用域对象:

1、在 Servlet 规范中,认为在服务端内存中可以在某些条件下为两个 servlet 之间提供数据共享方案的对象, 被称为【作用域对象】。
2、在 Servlet 规范中定义了多种类型的监听器,它们用于监听的事件源分别为 SerlvetConext 、 HttpSession 和 ServletRequest 这三个域对象。
3、 Servlet 规范下作用域对象:
ServletContext:全局作用域对象
HttpSession:会话作用域对象
HttpServletRequest:请求作用域对象

8个监听器接口和6个Event类

1、结合三个域对象, Servlet 监听主要有上下文监听、会话监听和请求监听三种类型。Servlet 2.4 和 JSP 2.0 总共有8个监听器接口和6个Event类
2、其中 HttpSessionAttributeListener 与 HttpSessionBindingListener 皆使用 HttpSessionBindingEvent ; HttpSessionListener 和 HttpSessionActivationListener则都使用HttpSessionEvent;其余Listener对应的Event如下所示:

监听对象 Listener接口 Event类
监听 Servlet 上下文 ServletContextListener ServletContextEvent
ServletContextAttributeListener ServletContextAttributeEvent
监听Session HttpSessionListener HttpSessionEvent
HttpSessionActivationListener
HttpSessionAttributeListener HttpSessionBindingEvent
HttpSessionBindingListener
监听Request ServletRequestListener ServletRequestEvent
ServletRequestAttributeListener ServletRequestAttributeEvent
HttpSessionBindingListener 和 HttpSessionListener的监听范围区别

1、 HttpSessionBindingListener 和 HttpSessionListener 之间的最大区别:HttpSessionListener 只需要设置到web.xml中就可以监听整个应用中的所有session。
2、HttpSessionBindingListener 必须实例化后放入某一个 session 中,才可以进行监听。从监听范围上比较, HttpSessionListener 设置一次就可以监听所有 session ,HttpSessionBindingListener 通常都是一对一的。

监听器接口实现类开发规范:(三步)

1、根据监听的实际情况,选择对应监听器接口进行实现。
2、重写监听器接口声明【监听事件处理方法】。
3、在 web.xml 文件将监听器接口实现类注册到Http服务器。

上下文监听

ServletContextListener 接口
  • 概述
    在 Web 应用程序启动时需要执行一些初始化任务时,可以编写实现了 ServletContextListener 接口的监听器类。在 ServletContextListener 接口中定义了两个事件处理方法,分别是 contextInitialize()contextDestroyed()
    在这里插入图片描述
    1、ServletContextListener 接口能够监听 ServletContext 对象的生命周期,实际上就是监听 Web 应用的生命周期。
    2、当 Servlet 容器启动或终止 Web 应用时,会触发 ServletContextEvent 事件,该事件由 ServletContextListener 来处理。在 ServletContextListener 接口中定义了处理 ServletContexEvent 事件的两个方法。
    contextInitialized( ServletContextEvent sce):当 Servlet 容器启动 Web 应用时调用该方法。在调用完该方法之后,容器再对 Filter 初始化,并且对那些在 Web 应用启动时就需要被初始化的 Servlet 。
    contextDestroyed( ServletContextEvent sce):当 Servlet 容器终止 Web 应用时调用该方法。在调用该方法之前,容器会先销毁所有的 Servlet 和 Filter 过滤器。
  • 代码示例
package com.aaa;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class OneListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("Servlet 容器启动 Web 应用");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("Servlet 容器终止 Web 应用");
    }
}

XML配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <listener>
        <listener-class>com.aaa.OneListener</listener-class>
    </listener>

</web-app>

启动:
在这里插入图片描述
关闭:
在这里插入图片描述

ServletContextAttributeListener接口

ServletContext 的属性是由 Web 应用程序中所有的 Servlet 所共享的。为保证属性在整个 Web 应用范围内的一致性,有必要监视 ServletContext 对象的任何属性的改变。ServletContextAttributeListener 侦听器就是为了这一目的而设立的。该侦听器是一个实现了接口Serv.letContextAttributelListener的Java类。 ServletContextAttributeListener 操作顺序图如图所示。
在这里插入图片描述

  • 方法
//增加属性
public void attributeAdded(ServletContextAttributeEvent scab);
//属性删除
public void attributeRemoved(ServletContextAttributeEvent scab);
//属性替换(第二次设置同一属性)
public void attributeRepalced(ServletContextAttributeEvent scab);

//ServletContextAttributeEvent事件:能取得设置属性的名称与内容
//得到属性名称
public String getName();
//取得属性的值
public Object getValue();
  • 例子
package com.aaa;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;

public class OneListener implements ServletContextAttributeListener {

    @Override
    public void attributeAdded(ServletContextAttributeEvent scab) {
        System.out.println("新增共享数据");
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent scab) {
        System.out.println("更新共享数据");
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent scab) {
        System.out.println("删除共享数据");
    }

}
package com.aaa;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class OneServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {

        ServletContext application = req.getServletContext();

        //新增共享数据
        application.setAttribute("key", 111);

        //更新共享数据
        application.setAttribute("key", 222);

        //删除共享数据
        application.removeAttribute("key");
    }
}

<servlet>
    <servlet-name>Servlet</servlet-name>
    <servlet-class>com.aaa.OneServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>Servlet</servlet-name>
    <url-pattern>/one</url-pattern>
</servlet-mapping>
    
//web.xml配置监听器
<listener>
    <listener-class>com.aaa.OneListener</listener-class>
</listener>

启动服务器访问:http://localhost:8080/Web/one
在这里插入图片描述

会话监听

HttpSessionListener 接口

HttpSessionListener 接口用于监听 HttpSession 对象的创建和销毁;
创建一个 Session 时,激发 SessionCreaed( HttpSessionEvent se )方法;
销毁一个 Session 时,激发 SessionDestroyed( HttpSessionEvent se )方法。

HttpSessionActivationListener 接口

监听 HttpSession 中的属性的操作。
当在 Session 增加一个属性时,激发 attributeAdded( HttpSessionBindingEvent se ) 方法;
当在 Session 删除一个属性时,激发 attributeRemoved( HttpSessionBindingEvent se ) 方法;
当在 Session 属性被重新设置时,激发 attributeReplaced( HttpSessionBindingEvent se ) 方法。

HttpSessionBindingListener接口

1、如果一个对象实现了 HttpSessionBindingListener 接口,当这个对象被绑定到 Session 中或从 Session 中删除时,Servlet容器会通知这个对象,这个对象在接收到通知后,做初始化操作或清除状态的操作。
2、HttpSessionBindingListener 接口提供了如下方法:
( public void valueBound( HttpSessionBindingEvent event ):当对象正在被绑定到 Session 中,Servlet 容器通知对象它将被绑定到某个会话并标识该会话。
public void valueUnbound(HttpSessionBindingEvent event):当从 Session 中删除对象时,Servlet 容器通知对象要从某个会话中取消对它的绑定并标识该会话容器通过 HttpSessionBindingEvent 对象来通知侦听器发生的事件的具体信息。提供了两种方法:
(1) public HttpSessionBindingEvent( HttpSession session, String name )
构造一个事件,通知对象它已经被绑定到会话,或者已经从会话中取消了对它的绑定。要接收该事件,对象必须实现HttpSessionBindingListener。
(2) public HttpSessionBindingEvent( HttpSession session, String name, Object value )
构造一个事件,通知对象它已经被绑定到会话,或者已经从会话中取消了对它的绑定。要接收该事件,对象必须实现 HttpSessionBindingListener 。
3、当 HttpSession 对象创建或者销毁时,Servlet 容器会产生 HttpSessionEvent 事件,而 HttpSessionListener 就是用来处理 HttpSessionEvent 事件的,它包含的两个方法就是分别用来处理 HttpSession 对象的创建和销毁。
4、HttpSessionBindingListener 和 HttpSessionListener 之间的最大区别:
HttpSessionListener 只需要设置到 web.xml 中就可以监听整个应用中的所有 session ,
HttpSessionBindingListener 必须实例化后放入某一个 session 中,才可以进行监听。

HttpSessionAttributelListener接口

监听 HttpSession 中的属性的操作。
当在 Session 增加一个属性时,激发 attributeAdded( HttpSessionBindingEvent se ) 方法;
当在 Session 删除一个属性时,激发 attributeRemoved( HttpSessionBindingEvent se ) 方法;
当在 Session 属性被重新设置时,激发 attributeReplaced( HttpSessionBindingEvent se ) 方法。

//HttpSessionBindingEvent事件:
public String getName();//取得属性的名称
public Object getValue();//取得属性的值
public HttpSession getSession();//取得当前的session

请求监听

ServletRequestListener

以下内容出自JAVAschool
ServletRequestListener 是用户响应监听器,用于对 Request 请求进行监听(创建、销毁)。

  • 方法
public void requestInitialized(ServletRequestEvent sre);//request初始化,对实现客户端的请求进行监听
public void requestDestroyed(ServletRequestEvent sre);//对销毁客户端进行监听,即当执行request.removeAttribute("XXX")时调用
// ServletRequestEvent 事件:
public ServletRequest getServletRequest();//取得一个ServletRequest对象
public ServletContext getServletContext();//取得一个ServletContext(application)对象
  • 例子(1)
//简单使用servletRequestListener来实现web浏览量的变化
package com.aaa;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import java.util.Date;

public class OneListener implements ServletRequestListener {

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("requestDestroyed" + "," + new Date());
        System.out.println("当前访问次数:" + sre.getServletContext().getAttribute("count"));
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("requestInitialized" + "," + new Date());
        Object count = sre.getServletContext().getAttribute("count");
        Integer cInteger = 0;
        if (count != null) {
            cInteger = Integer.valueOf(count.toString());
        }
        System.out.println("历史访问次数::" + count);
        cInteger++;
        sre.getServletContext().setAttribute("count", cInteger);
    }
}
    <listener>
        <listener-class>com.aaa.OneListener</listener-class>
    </listener>

在 ServletRequest 对象被建立的时候调用初始化方法,从内存中读取 ServletContext 对象的 count 属性,而后输出历史访问量。 同时在此基础上加一重新设置 ServletContext 对象的 count 属性的内容,当 ServletRequest 对象被销毁的时候调用销毁时的方法打印出当前浏览量,这样就简单的实现了 web 浏览的量的累加计数。
在这里插入图片描述
刷新一次,浏览量增加一次。
在这里插入图片描述

  • 例子(2)
    ServletRequestEvent 中的 getServletRequest() 方法。
package com.aaa;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

public class OneListener implements ServletRequestListener {

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println(sre. getServletRequest() + "销毁了! ! ");
        System.out.println("-------------------");
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println(sre. getServletRequest() + "创建了! ! ");
    }
}
//web.xml文件中注册监听器  
<!--注册针对ServletRequest对象进行监听的监听器-->
<listener>
	<listener-class>com.aaa.OneListener</listener-class>
</listener>

在这里插入图片描述
OneListener 类实现了 ServletRequestListener 接口,因此可以对 ServletRequest 对象的创建和销毁这两个动作进行监听。用户每一次访问都会创建 request 对象,当访问结束后, request 对象就会销毁。

ServletRequestAttributeListener

以下内容出自JAVAschool
ServletRequestAttributeListener 对 Request 的增删改属性进行监听。

  • 方法
public void attributeAdded(ServletRequestAttributeEvent srae);//增加属性
public void attributeRemoved(ServletRequestAttributeEvent srae);//属性删除
public void attributeReplaced(ServletRequestAttributeEvent srae);//属性替换(第二次设置同一属性)
// ServletRequestAttributeEvent 事件:能取得设置属性的名称与内容
public String getName();//得到属性名称
public Object getValue();//取得属性的值
  • 例子
/** 
 * Request请求时调用这个监听
 */  
package com.aaa;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;

public class OneListener implements ServletRequestListener, ServletRequestAttributeListener {

    @Override
    public void requestDestroyed (ServletRequestEvent s) {
        System.out.println("销毁了ServletReqeust");
    }

    @Override
    public void requestInitialized (ServletRequestEvent s) {
        System.out.println("创建了ServletReqeust");
        ServletRequest servletRequest = s.getServletRequest();
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String pathInfo = request.getServletPath();
        System.out.println("请求地址:" + pathInfo);
    }

    @Override
    public void attributeAdded (ServletRequestAttributeEvent srae) {
        HttpServletRequest request = (HttpServletRequest) srae.getServletRequest();
        System.out.println("增加request--->"+request.getAttribute("key"));
    }

    @Override
    public void attributeRemoved (ServletRequestAttributeEvent srae) {
        HttpServletRequest request = (HttpServletRequest) srae.getServletRequest();
        System.out.println("删除request--->"+request.getAttribute("key"));
    }

    @Override
    public void attributeReplaced (ServletRequestAttributeEvent srae) {
        HttpServletRequest request = (HttpServletRequest) srae.getServletRequest();
        if (request.getAttribute("key") != null) {
            System.out.println("替换request--->" + request.getAttribute("key"));
        }
    }
}

OneServlet 用于测试。

package com.aaa;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class OneServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {

        //新增request数据
        req.setAttribute("key", 111);

        //更新request数据
        req.setAttribute("key", 222);

        //删除request数据
        req.removeAttribute("key");
    }
}
//web.xml配置
<!-- 自定义ServletRquestListener的监听 --> 
<listener>
    <listener-class>com.aaa.OneListener</listener-class>
</listener>


<servlet>
    <servlet-name>Servlet</servlet-name>
    <servlet-class>com.aaa.OneServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>Servlet</servlet-name>
    <url-pattern>/one</url-pattern>
</servlet-mapping>

在这里插入图片描述

原文地址:https://www.cnblogs.com/yu011/p/14162125.html