监听器

作者: 码而优则仕 | 来源:发表于2020-08-26 08:43 被阅读0次

监听器

为了能够在 Servlet 应用程序中进行事件驱动编程,Servlet API 提供了一整套事件类和监听器接口。所有事件类均源自java.util.Event,并且监听器在以下三个不同级别中均可用:ServletContextHttpSession,ServletRequest.

监听器接口和注册

ServletContextListener

ServletContextAttributeListener

HttpSessionListener

HttpSessionActivationListener

HttpSessionAttributeListener

HttpSessionBindingListener

ServletRequestListener

ServletRequestAttributeListener

AsyncListener。

注册监听器有两种方式:注解(@WebListener)/在部署描述符(web.xml)中配置

<listener>
  <listener-class>
  </listener-class>
</listener>

ServletContext 监听器

在ServletContext 级别上有两个监听器接口:ServletContextListener,ServletContextAttributeListener

ServletContextListener:

ServletContextListener会对 ServletContext 的初始化和解构做出响应。ServletContext被初始化的时候,Servlet容器会在所有已注册的ServletContextListener中调用 contextInitialized 方法,方法签名如下:

  • void contextInitialized(ServletContextEvent event)

    当ServletContext要被解构和销毁时,Servlet容器会在所有已注册的ServletContextListener中调用 contextDestroyed 方法,方法签名如下:

  • void contextDestroyed(ServletContextEvent event)

    ServletContextEvent是 java.util.EventObject 类的派生类。其中定义了方法:

    ServletContext getServletContext()

实例如下:

JSTL 依赖引入:

<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
package cn.com.yuns.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.util.HashMap;
import java.util.Map;

/**
 * 以注解的方式申明监听器
 *
 * @author wsq
 * @version AppListener.java  2020/7/30  上午8:32 上午
 */
@WebListener
public class AppListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext servletContext = sce.getServletContext();
        Map<String, String> countries = new HashMap<>();
        countries.put("ca", "China");
        countries.put("jp", "Japan");
        countries.put("am", "American");
        servletContext.setAttribute("countries", countries);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }

}
<%--
  Created by IntelliJ IDEA.
  User: wsq
  Date: 2020/7/30
  Time: 8:36 上午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Country List</title>
</head>
<body>
we operate in these countries:
<ul>
    <c:forEach items="${countries}" var="country">
        <li>
                ${country.value}
        </li>
    </c:forEach>
</ul>
</body>

</html>

ServletContextAttributeListener:

每当ServletContext 中添加,删除或替换了某个属性时,所有注册的实现了ServletContextAttributeListener的监听器都会收到通知:

下面是这个监听器接口定义的三个方法:
  • void attributeAdded(ServletContextAttributeEvent event);

  • void attributeRemoved(ServletContextAttributeEvent event);

  • void attributeReplaced(ServletContextAttributeEvent event);

    在ServletContext 中,添加,删除,替换某个属性时,上上面的三个方法就会被分别调用。ServletContextAttributeEvent派生自 ServletContextAttribute

Session监听器

与HttpSession 有关的监听器接口有四个:HttpSessionListener,HttpSessionActivationListener,HttpSessionAttributeListener,HttpSessionBindingListener。

HttpSessionListener:

当有HttpSession 被创建或者销毁的时候,Servlet 容器就会调用所有已经注册的HttpSessionListener。

HttpSessionListener:定义了两个方法:

  • void sessionCteated(HttpSessionEvent event)

  • void sessionDestroyed(HttpSessionEvent event)

    方法参数 HttpSessionEvent 定义了一个方法:

    HttpSession getSession();

实例如下:

package cn.com.yuns.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author wsq
 * @version SessionListener.java  2020/7/30  上午8:59 上午
 */
@WebListener
public class SessionListener implements HttpSessionListener, ServletContextListener {


    /**
     * ServletContext 初始化的时候调用该方法,初始化用户人数为 0
     *
     * @param sce
     */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext servletContext = sce.getServletContext();
        servletContext.setAttribute("userCounter", new AtomicInteger());
    }

    /**
     * Session 会话被创建的时候,表示有新的用户访问网站,故而使用人数加一
     *
     * @param se
     */
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        ServletContext servletContext = session.getServletContext();
        AtomicInteger userCounter = (AtomicInteger) servletContext.getAttribute("userCounter");
        int userCount = userCounter.incrementAndGet();
        System.out.println("new user welcome current user is :" + userCount);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        ServletContext servletContext = session.getServletContext();
        AtomicInteger userCounter = (AtomicInteger) servletContext.getAttribute("userCounter");
        int userCount = userCounter.decrementAndGet();
        System.out.println("has user leave current user is :" + userCount);
    }
}

HttpSessionAttributeListener

当HttpSession中有添加,删除或者替换属性的时候就会被调用

  • void attributeAdded(HttpSessionBindingEvent event);

  • void attributeRemoved(HttpSessionBindingEvent event);

  • void attributeReplaced(HttpSessionBindingEvent event);

    由于 HttpSessionBindingEvent 是 HttpSessionEvent的子类,因此还可以在 HttpSessionAttributeListener 类中查到受影响的 HttpSession

HttpSessionActivationListener:

在分布式环境中,多个Servlet 容器会配置成可伸缩的,为了节约内存,Servlet容器可以对session属性进行迁移或者序列化。一般来说,当内存比较低时,相对较少访问的对象可以序列化到备用存储设备中,这样,Servlet容器就能够注意到哪些Session属性的类实现了HttpSessionActivationListener接口。

这个接口中定义了两个方法:

  • void sessionDidActivate(HttpSessionEvent event);

  • void sessionWillPassivate(HttpSessionEvent event);

    包含这个对象的HttpSession一旦被激活(Activate),就会调用sessionDidActivate 方法。Servlet 容器传递给该方法的HttpSessionEvent 能够获取到刚刚激活的 HttpSession。

    当包含该监听器的HttpSession 即将被钝化(Passivate)时,会调用sessionWillPassivate方法。

HttpSessionBindingListener

当 HttpSessionBindingListener绑定到HttpSession,或者取消绑定时,都会收到通知。如果一个类香知道什么时候绑定或者取消绑定到HttpSession上,那么这个类要实现HttpSessionBindingListener接口,然后将它的实例保存为session 属性,它就可以自动更新。再比如,一旦HttpSessionBindingListener与HttpSession取消绑定,它的实现类就可以释放占用的资源。

实例如下:

package cn.com.yuns.listener;

import lombok.Data;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

/**
 * @author wsq
 * @version Product.java  2020/7/30  上午11:13 上午
 */
@WebListener
@Data
public class Product implements HttpSessionBindingListener {

    private String id;

    private String name;

    private double price;

    /**
     * 绑定时调用该方法
     *
     * @param event
     */
    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        String attributeName = event.getName();
        System.out.println(attributeName + " valueBound");
    }

    /**
     * 解绑时调用该方法
     *
     * @param event
     */
    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        String attributeName = event.getName();
        System.out.println(attributeName + " valueUnbound");
    }
}

ServletRequest监听器:

在ServletRequest 级别上有三个监听器接口:ServletRequestListener,ServletRequestAttributeListener,和AsyncListener。

ServletRequestListener对ServletRequest的创建和销毁做出响应。在Servlet容器中是通过池来重用ServletRequest的,创建ServletRequest花费的时间相当于从池中获取它的时间,ServletRequest销毁时间则相当于它返回到池中的时间。

ServletRequestListener 接口定义了如下两个方法:

  • void requestInitialized(ServletRequestEvent event);

  • void requestDestroyed(ServletRequestEvent event);

    创建或从池中取出 ServletRequest 时会调用 requestInitialized方法,ServletRequest被销毁或返回池中时会调用 requestDestroyed 方法

    ServletRequestEvent 参数对象中定义了 获取 ServletRequest的方法,此外还定义了返回ServletContext的方法。

ServletRequestAttributeListener

当在ServletRequest中添加,删除或者替换某个属性的时候,会调用 ServletRequestAttributeListener ;该接口定义了三个方法:

  • void attributeAdded(ServletRequestAttributeEvent event);

  • void attributeRemoved(ServletRequestAttributeEvent event);

  • void attributeReplaced(ServletRequestAttributeEvent event);

相关文章

  • SpringBoot--监听器解析

    监听器模式 监听器模式有要素 事件 监听器 广播器 触发机制 系统监听器 监听器 ApplicationListe...

  • 监听器

    一、监听器定义 现实生活 -web监听器 二、web监听器应用 三、创建监听器 1、创建一个实现监听器接口的类。 ...

  • JavaWeb - Listener

    监听器 实现一个监听器的接口. 编写一个监听器实现监听器的接口 web.xml 中注册监听器 看情况是否使用

  • Spring 监听器listener原理-基本使用(一)

    Spring 监听器listener原理-基本使用(一) Spring 监听器listener原理-手写监听器(二...

  • JavaEE_day23_Listener(监听器)

    一、监听器(Listener): 1.什么是监听器? 监听器就是监听某个对象的的状态变化的组件 监听器的相关概念:...

  • tomcat内存马Listener篇

    什么是监听器 监听器类型 java共有三种类型的监听器 ServletContext对象的监听器 它能够监听 Se...

  • 监听器

    一.监听器定义 二.web监听器的用途 三.创建监听器 创建一个实现监听器接口类( 实现的是ServletCont...

  • Bukkit插件开发教程 - 监听器

    监听器 - Listener 学习目标 理解监听器的意义 了解监听器的注册 @EventHandler注解的作用 ...

  • 2019-02-26 web监听器(慕课网学习笔记)

    1 监听器的定义 2 web中监听器的定义 3 web监听器的常用用途 4 创建第一个监听器 常规的web项目,需...

  • 23. 监听器

    12 监听器 实现一个监听器的接口 编写一个监听器package com.karl.listener;import...

网友评论

      本文标题:监听器

      本文链接:https://www.haomeiwen.com/subject/tgjrrktx.html