Listener监听器
Listener监听器
一、前言
(1)概念
Listener(监听器)是一种机制,用于监听和响应特定的事件。它可以感知并响应与应用程序相关的事件,从而执行相应的逻辑处理。
事件是在应用程序运行过程中发生的特定动作或状态改变。例如,Web应用程序的启动和关闭、请求的到达和完成、会话的创建和销毁等都被认为是事件。监听器会注册对这些事件的感兴趣,并在事件发生时调用相应的回调方法来执行预定的业务逻辑。
监听器的概念可以类比于现实生活中的观察者模式。在观察者模式中,一个对象(观察者)注册对另一个对象(被观察者)的事件感兴趣,并在被观察者触发相应事件时得到通知并执行相应操作。类似地,在JavaWeb应用程序中,监听器充当观察者的角色,可以监听和响应特定的事件。
通过使用监听器,开发者可以将应用程序的关键行为和状态抽象成事件,并在需要的时候采取相应的措施。比如,在Web应用程序启动时,可以使用ServletContextListener来进行初始化操作;在每次请求到达时,可以使用ServletRequestListener来获取请求信息等。
监听器的设计使得应用程序更加灵活和可扩展。它提供了一种松耦合的方式来解耦应用程序的不同模块,并实现事件驱动的编程模型。监听器是实现Web应用程序的事件处理和扩展性的重要组成部分。
(2)价值所在
监听器(Listener)在JavaWeb应用程序中具有重要的意义和价值,主要体现在以下几个方面:
-
实现事件驱动编程:监听器的核心概念是基于事件的触发和响应,它使得开发者可以将应用程序的关键行为和状态抽象成事件,并在事件发生时执行相应的逻辑处理。通过监听器,开发者可以实现事件驱动编程的思想,更加灵活地响应应用程序中的各种事件。
-
解耦和模块化:监听器解耦了应用程序中不同模块之间的依赖关系。它提供了一种松耦合的方式来将事件和事件处理的逻辑相互分离,使得不同的模块可以独立地进行开发和维护。通过监听器,开发者可以将特定事件的处理逻辑集中到监听器中,从而提高代码的可读性和可维护性。
-
增强可扩展性:使用监听器可以有效地增强应用程序的可扩展性。当应用程序需要添加新的功能或处理新的事件时,可以通过编写自定义的监听器来实现。通过监听器,可以在不修改已有代码的情况下,将新的功能集成到应用程序中,从而实现应用程序的动态扩展。
-
提供通用的解决方案:一些监听器是Web容器预先定义的,如ServletContextListener、ServletRequestListener和HttpSessionListener等。这些监听器提供了一些通用的解决方案,可用于应用程序中常见的场景,如应用程序的初始化、请求的处理、会话管理等。通过使用这些通用的监听器,开发者可以以更加快速和方便的方式完成常见功能的实现。
所以它提供了一种事件驱动的编程模型,帮助开发者实现模块间的解耦和功能的扩展,以及提供通用的解决方案。监听器在开发Web应用程序时是一种强大的工具,可以提升代码的可维护性、可扩展性和可读性。
二、Listener监听器介绍
- Listener 监听器它是 JavaWeb 的三大组件之一。 JavaWeb 的三大组件分别是: Servlet 程序、 Listener 监听器、 Filter 过滤器
- Listener 是 JavaEE 的规范,就是接口
- 监听器的作用是,监听某种变化 ( 一般就是对象创建 / 销毁 , 属性变化 ), 触发对应方法完成 相应的任务
- JavaWeb 中的监听器(共八个) , 目前最常用的是 ServletContextListener
三、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,其添加操作结果为
访问 http://localhost:8080/Listener/replace.jsp,其修改操作结果为
访问 http://localhost:8080/Listener/remove.jsp,其移除操作结果为
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,其添加操作结果为
访问 http://localhost:8080/Listener/session/remove.jsp,其移除操作结果为
五、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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!