长风破浪会有时|

粤先生

园龄:10个月粉丝:1关注:2

Listener监听器

Listener监听器

一、前言

(1)概念

Listener(监听器)是一种机制,用于监听和响应特定的事件。它可以感知并响应与应用程序相关的事件,从而执行相应的逻辑处理。

事件是在应用程序运行过程中发生的特定动作或状态改变。例如,Web应用程序的启动和关闭、请求的到达和完成、会话的创建和销毁等都被认为是事件。监听器会注册对这些事件的感兴趣,并在事件发生时调用相应的回调方法来执行预定的业务逻辑。

监听器的概念可以类比于现实生活中的观察者模式。在观察者模式中,一个对象(观察者)注册对另一个对象(被观察者)的事件感兴趣,并在被观察者触发相应事件时得到通知并执行相应操作。类似地,在JavaWeb应用程序中,监听器充当观察者的角色,可以监听和响应特定的事件。

通过使用监听器,开发者可以将应用程序的关键行为和状态抽象成事件,并在需要的时候采取相应的措施。比如,在Web应用程序启动时,可以使用ServletContextListener来进行初始化操作;在每次请求到达时,可以使用ServletRequestListener来获取请求信息等。

监听器的设计使得应用程序更加灵活和可扩展。它提供了一种松耦合的方式来解耦应用程序的不同模块,并实现事件驱动的编程模型。监听器是实现Web应用程序的事件处理和扩展性的重要组成部分。

(2)价值所在

监听器(Listener)在JavaWeb应用程序中具有重要的意义和价值,主要体现在以下几个方面:

  • 实现事件驱动编程:监听器的核心概念是基于事件的触发和响应,它使得开发者可以将应用程序的关键行为和状态抽象成事件,并在事件发生时执行相应的逻辑处理。通过监听器,开发者可以实现事件驱动编程的思想,更加灵活地响应应用程序中的各种事件。

  • 解耦和模块化:监听器解耦了应用程序中不同模块之间的依赖关系。它提供了一种松耦合的方式来将事件和事件处理的逻辑相互分离,使得不同的模块可以独立地进行开发和维护。通过监听器,开发者可以将特定事件的处理逻辑集中到监听器中,从而提高代码的可读性和可维护性。

  • 增强可扩展性:使用监听器可以有效地增强应用程序的可扩展性。当应用程序需要添加新的功能或处理新的事件时,可以通过编写自定义的监听器来实现。通过监听器,可以在不修改已有代码的情况下,将新的功能集成到应用程序中,从而实现应用程序的动态扩展。

  • 提供通用的解决方案:一些监听器是Web容器预先定义的,如ServletContextListener、ServletRequestListener和HttpSessionListener等。这些监听器提供了一些通用的解决方案,可用于应用程序中常见的场景,如应用程序的初始化、请求的处理、会话管理等。通过使用这些通用的监听器,开发者可以以更加快速和方便的方式完成常见功能的实现。

所以它提供了一种事件驱动的编程模型,帮助开发者实现模块间的解耦和功能的扩展,以及提供通用的解决方案。监听器在开发Web应用程序时是一种强大的工具,可以提升代码的可维护性、可扩展性和可读性。

二、Listener监听器介绍

img

  1. Listener 监听器它是 JavaWeb 的三大组件之一。 JavaWeb 的三大组件分别是: Servlet 程序、 Listener 监听器、 Filter 过滤器
  2. Listener 是 JavaEE 的规范,就是接口
  3. 监听器的作用是,监听某种变化 ( 一般就是对象创建 / 销毁 , 属性变化 ), 触发对应方法完成 相应的任务
  4. JavaWeb 中的监听器(共八个) , 目前最常用的是 ServletContextListener

image-20240407211310283

三、Listener的生命周期

监听器的生命周期与Web应用程序的生命周期密切相关。

ServletContextListener:ServletContextListener会在Web应用程序启动时起作用,并在Web应用程序关闭时销毁。具体来说,当Web容器启动时会触发contextInitialized()方法,开发者可以在这个方法中进行一些初始化操作;当Web容器关闭时会触发contextDestroyed()方法,开发者可以在这个方法中进行一些资源释放、清理操作。

ServletRequestListener:ServletRequestListener会在每次客户端请求到达服务器时起作用,并在服务器响应完成后销毁。具体来说,当客户端发送请求到达服务器时会触发requestInitialized()方法,开发者可以在这个方法中获取和处理请求相关的信息;当服务器响应完成后会触发requestDestroyed()方法,开发者可以在这个方法中进行一些善后操作。

HttpSessionListener:HttpSessionListener会在每次HttpSession创建和销毁时起作用。具体来说,当用户访问Web应用程序时,如果尚未创建HttpSession,会触发sessionCreated()方法,在这个方法中可以进行一些会话管理的操作;当HttpSession被销毁时,会触发sessionDestroyed()方法,在这个方法中可以进行一些会话清理的操作。

注意,监听器是通过在web.xml配置文件中声明来启用的。开发者需要在web.xml文件中添加相应的监听器声明,告诉Web容器要监听哪些事件,并指定相应的监听器类。

四、Listener的监听器

三大域:

  • ServletContext

  • HttpSession

  • ServletRequest

监听器:

ServletContext

(1)ServletContextListener
  • void contextInitialized(ServletContextEvent sce) :执行应用程序启动时的初始化操作,比如加载配置文件、初始化数据库连接池
  • void contextDestroyed(ServletContextEvent sce) :执行应用程序关闭时的清理操作,比如关闭数据库连接池、释放资源
(2)ServletContextAttributeListener
  • void attributeAdded(ServletContextAttributeEvent event)当ServletContext属性被添加时,你可以获取属性的名称和值,并执行相应的操作,如记录日志、更新缓存等。
  • void attributeRemoved(ServletContextAttributeEvent event)当ServletContext属性被移除时,你可以获取属性的名称和值,并执行相应的操作,如清理资源、撤销缓存等。
  • void attributeReplaced(ServletContextAttributeEvent event)当ServletContext属性被替换时,你可以同时获取属性的旧值和新值,并执行相应的操作,如更新缓存、重新加载配置等。

HttpSession

(1)HttpSessionListener
  • void sessionCreated(HttpSessionEvent se)当HttpSession被创建时,你可以获取HttpSession的ID,并执行相应的操作,如记录日志、初始化用户会话数据等。
  • void sessionDestroyed(HttpSessionEvent se)当HttpSession被销毁时,你可以获取HttpSession的ID,并执行相应的操作,如清理资源、保存用户会话状态等。
(2)HttpSessionAttributeListener
  • void attributeAdded(HttpSessionBindingEvent event)当向HttpSession中添加属性时,你可以获取属性的名称和值,并执行相应的操作,如记录日志、更新相关数据等。
  • void attributeRemoved(HttpSessionBindingEvent event)当从HttpSession中移除属性时,你可以获取属性的名称和值,并执行相应的操作,如记录日志、清除相关数据等。
  • void attributeReplaced(HttpSessionBindingEvent event)当替换HttpSession中的属性时,你可以获取属性的名称、旧值和新值,并执行相应的操作,如记录日志、更新相关数据等。

ServletRequest

(1)ServletRequestListener
  • void requestInitialized(ServletRequestEvent sre)创建request时,记录请求信息,如URL、参数等。
  • void requestDestroyed(ServletRequestEvent sre)销毁request时,执行清理操作,如释放资源。
(2)ServletRequestAttributeListener
  • void attributeAdded(ServletRequestAttributeEvent event)当向ServletRequest中添加属性时,你可以获取属性的名称和值,并执行相应的操作,如记录日志、更新相关数据等。通过event.getServletRequest()可以获取到HttpServletRequest对象,进而可以获取请求的URL等信息。
  • void attributeRemoved(ServletRequestAttributeEvent event)当从ServletRequest中移除属性时,你可以获取属性的名称和值,并执行相应的操作,如记录日志、清除相关数据等。同样,可以通过event.getServletRequest()获取到HttpServletRequest对象。
  • void attributeReplaced(ServletRequestAttributeEvent event)当替换ServletRequest中的属性时,你可以获取属性的名称、旧值和新值,并执行相应的操作,如记录日志、更新相关数据等。同样,通过event.getServletRequest()可以获取到HttpServletRequest对象。

事件对象

(1)ServletContextEvent事件对象

  • ServletContext getServletContext():返回ServletContext对象

(2)ServletContextAttributeEvent事件对象

  • ServletContext getServletContext():返回ServletContext对象
  • String getName():获取属性名
  • Object getValue():获取属性值

(3)HttpSessionEvent事件对象

  • HttpSession getSession():返回HttpSession对象

(4)HttpSessionBindingEvent事件对象

  • String getName():获取属性名
  • HttpSession getSession():获取HttpSession对象
  • Object getValue():获取属性值

(5)ServletRequestEvent事件对象

  • ServletRequest getServletRequest():返回ServletRequest对象

  • ServletContext getServletContext():返回ServletContext对象

(6)ServletRequestAttributeEvent事件对象

  • String getName():获取属性名
  • Object getValue():获取属性值

感知监听器

  • HttpSessionBindingEvent和ServletRequestAttributeEvent都是感知监听器

  • 它用来添加到javaBean上,而不是添加到三大域上

  • 这两个监听器都不需要在web.xml中注册

HttpSessionBindingEvent:添加到javabean上,javabean就知道自己是否被添加到session中了。

演示代码

1. 编写监听器

以 ServletContextListener 监听器为例,编写一个简单的监听器。

  • 创建一个监听文件AListener
  • 在web.xml文件配置<Listener>
  • 加载到Tomcat,启动服务器

AListener.java

public class AListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext开始监听...");
    }

    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext结束监听...");
    }
}

在web.xml文件配置<Listener>

<?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>cn.web.listener.AListener</listener-class>
    </listener>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

2. 编写监听器操作

以 ServletContextAttributeListener 监听器为例,编写其增删改查等操作。

  • 编写一个BListener文件
  • 在web.xml中配置<listener>
  • 编写index.jsp、remove.jsp和replace.jsp文件
  • 加载到Tomcat,启动服务器

BListener.java

public class BListener implements ServletContextAttributeListener {
    public void attributeAdded(ServletContextAttributeEvent scae) {
        System.out.println("向app中添加了一名为:" + scae.getName() + ",值为:" + scae.getValue() + "的属性");
    }

    public void attributeRemoved(ServletContextAttributeEvent scae) {
        /**
        * 这里的scae.getValue()获得是老值
        * 新值在scae.getServletContext().getAttribute(scae.getName()))
        */
        System.out.println(scae.getName() + "=" +scae.getValue() + "," + scae.getServletContext().getAttribute(scae.getName()));
    }

    public void attributeReplaced(ServletContextAttributeEvent scae) {
        System.out.println(scae.getName() + "=" + scae.getValue());
    }
}

在web.xml中配置<listener>

<?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>cn.web.listener.BListener</listener-class>
    </listener>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

index.jsp

<body>
  <%
    application.setAttribute("xxx","XXX");
  %>
</body>

remove.jsp

<body>
<%
    application.removeAttribute("xxx");
%>
</body>

replace.jsp

<body>
<%
    application.setAttribute("xxx","YYY");
%>
</body>

访问 http://localhost:8080/Listener/index.jsp,其添加操作结果为

image-20240408155750494

访问 http://localhost:8080/Listener/replace.jsp,其修改操作结果为

image-20240408160141113

访问 http://localhost:8080/Listener/remove.jsp,其移除操作结果为

image-20240408160330884

3. 编写感知监听器

以 HttpSessionBindingListener 监听器为例,编写一个简单的感知监听器

  • 编译一个User类实现 HttpSessionBindingListener 接口
  • 在web文件下创建名为session文件
  • 在session文件下,编写add.jsp和remove.jsp文件
  • 无需配置web.xml
  • 加载到Tomcat,启动服务器

User.java

public class Uesr implements HttpSessionBindingListener {
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    public Uesr() {
        super();
    }
    public Uesr(String username,String password){
        super();
        this.username = username;
        this.password = password;
    }

    public void valueBound(HttpSessionBindingEvent event) {
        System.out.println("session已绑定User...");
    }

    public void valueUnbound(HttpSessionBindingEvent event) {
        System.out.println("session已解绑User...");
    }
}

add.jsp

<body>
<%
cn.web.listener.Uesr user = new cn.web.listener.Uesr();
session.setAttribute("user", user);
%>
</body>

remove.jsp

<body>
<%
    session.removeAttribute("user");
%>
</body>

访问 http://localhost:8080/Listener/session/add.jsp,其添加操作结果为

image-20240408161525814

访问 http://localhost:8080/Listener/session/remove.jsp,其移除操作结果为

image-20240408161614429

五、Session简介

1. 什么是序列化

序列化是将对象或数据结构转换为可存储或传输的格式(例如,保存到文件,或通过网络发送)的过程。反序列化是序列化的逆过程,即将序列化的信息重新转换成原始的对象或数据结构。

2. Session的序列化

一般来说,服务器启动后,就不会再关闭了,但是如果逼不得已需要重启,而用户会话还在进行相应的操作,这时就需要使用序列化将session信息保存起来放在硬盘,服务器重启后,又重新加载。这样就保证了用户信息不会丢失,实现永久化保存。

3.演示Session序列化

新建一个项目,放入两个简单的jsp

a.jsp

<body>
<h1>向session中保存数据</h1>
<%
    session.setAttribute("xxx","我是session!!!");
%>
</body>

b.jsp

<body>
<h1>获取session中的数据</h1>
	<%
    	session.getAttribute("xxx");
	%>
</body>

我们先打开浏览器访问a.jsp页面,此时已经向session中保存了一个名为xxx的属性,这个时候我们关闭服务器,我们会发现在服务器的目录生成了这样一个文件:

在这里插入图片描述

上面的这个就是session的序列化文件,这个时候我们再次重启服务器,就可以发现这个文件自己消失了:在这里插入图片描述

上述这个过程,我们就称之为session的序列化。

4. Session的反序列化

所谓Session的反序列化,其实就是把session的序列化功能关闭。

  • 只需要打开tomcat下conf目录下的context.xml文件进行修改就可以了

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
    
  • 打开注释就关闭了session的序列化

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    
    <Manager pathname="" />
    

5.Session的钝化和活化

  • Session的钝化:把闲置的session放到硬盘上;

  • Session的活化:当要再次使用到闲置的session时候再把它读取到内存中。

配置Session的钝化

  • tomcat目录下的conf文件夹中的context.xml进行配置

    <Context>
    	<!-- 如果session在1分钟内没有使用,那么Tomcat就会钝化它 -->
    	<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
            
    		<!-- 把session序列化到Tomcat\work\Catalina\localhost\listener\mysession目录下。 -->
    		<Store className="org.apache.catalina.session.FileStore" directory="mysession"/>
    	</Manager>
    </Context>
    
  • 重新访问a.jsp文件,等待一分钟,mysession目录下会生成session文件,此时已经实现session的钝化在这里插入图片描述

  • 重新访问b.jsp,就是session的活化过程了,但是上面的这个文件是不会消失的。

本文作者:粤先生

本文链接:https://www.cnblogs.com/magicYue/p/18174183

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   粤先生  阅读(244)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起