实验六~Web事件处理与过滤器
1. 创建一个名为exp06的Web项目,编写、部署、测试一个ServletContext事件监听器。

BookBean代码
package org.example.beans;import java.io.Serializable;/*** Created with IntelliJ IDEA.* Description:* User: Li_yizYa* Date: 2023—04—29* Time: 18:39*/
@SuppressWarnings("serial")
public class BookBean implements Serializable {private String bookId;private String title;private String author;private String publisher;private double price;public String getBookId() {return bookId;}public void setBookId(String bookId) {this.bookId = bookId;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public String getPublisher() {return publisher;}public void setPublisher(String publisher) {this.publisher = publisher;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}
}
BookDao代码
package org.example.dao;import org.example.beans.BookBean;import java.sql.*;
import java.util.ArrayList;
import java.util.List;/*** Created with IntelliJ IDEA.* Description:* User: Li_yizYa* Date: 2023—04—29* Time: 18:41*/
public class BookDao {private static Connection c;public BookDao() {try {Class.forName("com.mysql.jdbc.Driver");String url = "jdbc:mysql://localhost:3306/web_test";c = DriverManager.getConnection(url, "root", "142516");} catch (Exception e) {e.printStackTrace();}}public List<BookBean> getBooks() {try {String sql = "select * from books";PreparedStatement ps = c.prepareStatement(sql);ResultSet rs = ps.executeQuery();List<BookBean> books = new ArrayList<>();while (rs.next()) {BookBean b = new BookBean();b.setBookId(rs.getString("book_id"));b.setAuthor(rs.getString("author"));b.setTitle(rs.getString("title"));b.setPublisher(rs.getString("publisher"));b.setPrice(rs.getDouble("price"));books.add(b);}return books;} catch (Exception e) {throw new RuntimeException("查询数据库出错", e);}}
}
【步骤1】编写监听器类MyServletContextListener.java,Web应用程序启动时创建一个数据源对象,并将其保存在ServletContext作用域中,Web应用销毁时将其清除;在ServletContext对象上添加属性、删除属性和替换属性时,在Tomcat日志中记录有关信息,包括提示信息、属性名和属性值等。
MyServletContextListener.java
package org.example.config;import javax.servlet.*;
import java.util.Date;/*** Created with IntelliJ IDEA.* Description:* User: Li_yizYa* Date: 2023—04—26* Time: 22:40*/
public class MyServletContextListener implements ServletContextListener, ServletContextAttributeListener {private ServletContext context = null;@Overridepublic void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {context = servletContextAttributeEvent.getServletContext();context.log("添加属性: " + servletContextAttributeEvent.getName()+ ": " + servletContextAttributeEvent.getValue());}@Overridepublic void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {context = servletContextAttributeEvent.getServletContext();context.log("删除属性: " + servletContextAttributeEvent.getName()+ ": " + servletContextAttributeEvent.getValue());}@Overridepublic void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {context = servletContextAttributeEvent.getServletContext();context.log("替换属性: " + servletContextAttributeEvent.getName()+ ": " + servletContextAttributeEvent.getValue());}@Overridepublic void contextInitialized(ServletContextEvent servletContextEvent) {context = servletContextEvent.getServletContext();context.log("应用程序已启动: " + new Date());}@Overridepublic void contextDestroyed(ServletContextEvent servletContextEvent) {context = servletContextEvent.getServletContext();context.log("应用程序已销毁: " + new Date());}
}
【步骤2】在web.xml文件中注册监听器类。
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><listener><listener-class>org.example.config.MyServletContextListener</listener-class></listener>
</web-app>
【步骤3】编写监听器测试页面:contextListenerTest.jsp:使用监听器创建的数据源对象连接是一次实验创建的MySQL数据库test,以表格的形式显示其中books数据表的所有内容。
contextListenerTest.jsp
<%@ page import="java.util.*" %>
<%@ page import="org.example.beans.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<jsp:useBean id="book" class="org.example.dao.BookDao" scope="session" />
<html>
<head><title>contextListenerTest</title>
</head><body><table width="500" height="256" border="1"><tr><th scope="col">bookid</th><th scope="col">title</th><th scope="col">author</th><th scope="col">publisher</th><th scope="col">price</th></tr><%List<BookBean> bookList = book.getBooks();for (BookBean books : bookList) {String book_id = books.getBookId();String title = books.getTitle();String author = books.getAuthor();String publisher = books.getPublisher();double price = books.getPrice();%><tr><td><%=book_id%> </td><td><%=title%></td><td><%=author%></td><td><%=publisher%></td><td><%=price%></td></tr><% } %></table>
</body>
</html>


【步骤5】检查日志文件
打开<CATALINA_HOME>\logs目录中的localhost.yyyy-mm-dd.log日志文件,查看执行事件监听器后写到日志文件中的信息。

2. 编写一个HttpSession事件监听器用来记录当前在线人数。
首先创建一个SessionBean类,用来记录sessionID和注册时间

package org.example.beans;import java.io.Serializable;/*** Created with IntelliJ IDEA.* Description:* User: Li_yizYa* Date: 2023—04—29* Time: 22:17*/
@SuppressWarnings("serial")
public class SessionBean implements Serializable {private String id;private String creationTime;public SessionBean(String id, String creationTime) {this.id = id;this.creationTime = creationTime;}public SessionBean() {}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getCreationTime() {return creationTime;}public void setCreationTime(String creationTime) {this.creationTime = creationTime;}
}
【步骤1】编写MySessionListener监听器处理类,监视Web应用会话创建事件:每创建一个新的会话对象,就将其保存到会话对象的列表数组中,并将用户会话对象列表保存在ServletContext作用域中的sessionList属性中,同时向日志中写入“创建一个新会话”以及该会话的ID。当一个会话对象被删除时,从用户会话对象列表中删除该会话对象并保存,同时向日志中写入“删除一个会话”以及该会话的ID。
package org.example.config;import org.example.beans.SessionBean;import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;/*** Created with IntelliJ IDEA.* Description:* User: Li_yizYa* Date: 2023—04—29* Time: 21:59*/
public class MySessionListener implements HttpSessionListener {@Overridepublic void sessionCreated(HttpSessionEvent httpSessionEvent) {ServletContext application = httpSessionEvent.getSession().getServletContext();List<SessionBean> sessionList = (List<SessionBean>)application.getAttribute("sessionList");if (sessionList == null) {sessionList = new ArrayList<>();application.setAttribute("sessionList", sessionList);}long time = httpSessionEvent.getSession().getCreationTime();Date date = new Date(time);SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String creationTime = sd.format(date);SessionBean sessionBean = new SessionBean(httpSessionEvent.getSession().getId(),creationTime);sessionList.add(sessionBean);application.log("创建一个新会话,其id为: " + httpSessionEvent.getSession().getId());}@Overridepublic void sessionDestroyed(HttpSessionEvent httpSessionEvent) {ServletContext application = httpSessionEvent.getSession().getServletContext();List<SessionBean> sessionList = (List<SessionBean>)application.getAttribute("sessionList");String sessionId = httpSessionEvent.getSession().getId();for(SessionBean session : sessionList) {if (session.getId().equals(sessionId)) {sessionList.remove(session);}}application.log("删除一个新会话,其id为: " + sessionId);application.setAttribute("sessionList", sessionList);}
}
【步骤2】在web.xml文件中注册该事件监听器。
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><listener><listener-class>org.example.config.MyServletContextListener</listener-class></listener><listener><listener-class>org.example.config.MySessionListener</listener-class></listener>
</web-app>
【步骤3】编写一个测试该监听器的页面sessionDisplay.jsp,显示当前应用所有在线的会话对象的id及创建时间。多打开几个浏览器窗口,模拟多用户访问,查看多用户会话统计出的结果。
<%@ page import="java.util.*" %>
<%@ page import="org.example.beans.*" %>
<%@ page contentType="text/html;charset=utf-8" %>
<html>
<head><title>sessionDisplay</title>
<style>td{text-align: center;}
</style>
</head>
<body><table width="500" height="256" border="1"><tr><th scope="col">会话id</th><th scope="col">创建时间</th></tr><%ServletContext context = getServletConfig().getServletContext();List<SessionBean> sessionList = (List<SessionBean>) context.getAttribute("sessionList");for (SessionBean s : sessionList) {String id = s.getId();String creationTime = s.getCreationTime();%><tr><td><%=id%> </td><td><%=creationTime%></td></tr><% } %></table>
</body>
</html>

3. 编写一个ServletRequestListener监听器,记录某个页面自应用程序启动以来被访问的次数。
【步骤1】编写监听器接口MyRequestListener,在对指定页面onlineCount.jsp发送请求时进行该页面访问次数计数器累加,并将计数器变量保存到应用作用域的属性中。
package org.example.config;import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;/*** Created with IntelliJ IDEA.* Description:* User: Li_yizYa* Date: 2023—04—30* Time: 0:04*/
public class MyRequestListener implements ServletRequestListener {private int count = 0;@Overridepublic void requestDestroyed(ServletRequestEvent servletRequestEvent) {}@Overridepublic void requestInitialized(ServletRequestEvent servletRequestEvent) {HttpServletRequest request1 = (HttpServletRequest) servletRequestEvent.getServletRequest();if(request1.getRequestURI().equals("/exp06/onlineCount.jsp")){count++;servletRequestEvent.getServletContext().setAttribute("count",new Integer(count));}}
}
【步骤2】在web.xml文件中注册该监听器。
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><listener><listener-class>org.example.config.MyServletContextListener</listener-class></listener><listener><listener-class>org.example.config.MySessionListener</listener-class></listener><listener><listener-class>org.example.config.MyRequestListener</listener-class></listener>
</web-app>
【步骤3】编写一个JSP页面onlineCount.jsp。
<%@ page contentType="text/html;charset=utf-8" language="java" %>
<html>
<head><title>Listener test</title>
</head>
<body>
欢迎您,您的IP地址是<%= request.getRemoteAddr() %>
<p>自应用程序启动以来,该页面被访问了
<font color="blue" ><%=application.getAttribute("count")%>
</font>次<br>
</body>
</html>
【步骤4】启动多个浏览器窗口访问该jsp页面,展示并分析程序的运行结果。

相关文章:
实验六~Web事件处理与过滤器
1. 创建一个名为exp06的Web项目,编写、部署、测试一个ServletContext事件监听器。 BookBean代码 package org.example.beans;import java.io.Serializable;/*** Created with IntelliJ IDEA.* Description:* User: Li_yizYa* Date: 2023—04—29* Time: 18:39*/ Su…...
刷题4.28
1、 开闭原则软件实体(模块,类,方法等)应该对扩展开放,对修改关闭,即在设计一个软件系统模块(类,方法)的时候,应该可以在不修改原有的模块(修改关…...
做了一年csgo搬砖项目,还清所有债务:会赚钱的人都在做这件事 !
前段時间,在网上看到一句话:有什么事情,比窮更可怕? 有人回答说:“又忙又窮。” 很扎心,却是绝大多数人的真实写照。 每天拼死拼活的996,你有算过你的時间值多少钱? 我们来算一笔…...
线性回归模型(7大模型)
线性回归模型(7大模型) 线性回归是人工智能领域中最常用的统计学方法之一。在许多不同的应用领域中,线性回归都是非常有用的,例如金融、医疗、社交网络、推荐系统等等。 在机器学习中,线性回归是最基本的模型之一&am…...
VP记录:Codeforces Round 868 (Div. 2) A~D
传送门:CF A题:A-characteristic 构造一个只有 1 , − 1 1,-1 1,−1的数组,满足乘积为 1 1 1的数对的个数为 k k k. 发现 n n n的范围很小,考虑直接暴力枚举数组中 1 1 1的个数,记为 i i i,那么对于1的所有数对来说,我们有 i ∗ ( i − 1 ) / 2 i*(i-1)/2 i∗(i−1)/2个,然后…...
【VQ-VAE-2论文精读】Generating Diverse High-Fidelity Images with VQ-VAE-2
【VQ-VAE-2论文精读】Generating Diverse High-Fidelity Images with VQ-VAE-2 0、前言Abstract1 Introduction2 Background2.1 Vector Quantized Variational AutoEncoder3 Method3.1 Stage 1: Learning Hierarchical Latent Codes3.2 Stage 2: Learning Priors over Latent C…...
并发编程基石:管程
大家好,我是易安! 如果有人问我学习并发并发编程,最核心的技术点是什么,我一定会告诉他,管程技术。Java语言在1.5之前,提供的唯一的并发原语就是管程,而且1.5之后提供的SDK并发包,也…...
电路中噪声来源
电路包括不同的部件和芯片,所有都有可能成为噪声的来源。例如,电阻会带来热噪声,这个噪声为宽频噪声,几乎涵盖所有频率范围;运算放大器其芯片内部会产生噪声;而 ADC产生的量化噪声相较于其他器件࿰…...
JAVASE的全面总结
(未完待续) 五、子类与继承 5.1 子类与父类 继承是一种由已有的类创建新类的机制。利用继承,我们可以先创建一个共有属性的一般类,根据该一般类再创建具有特殊属性的新类,新类继承一般类的状态和行为,并…...
关于repeater录制的流量子调用的identity中带有~S的情况
前段时间同事问我,我们录制的流量中,尤其是dubbo的子调用显示经常他的末尾会带上一个小尾巴这个是什么意思呢,其实之前我没有太在意这个事情,只是同事这么疑问了,确实激起了好奇心,所以就差了下 到底是什么…...
Java面试题队列
Java中的队列都有哪些,有什么区别 1. ArrayDeque, (数组双端队列) 2. PriorityQueue, (优先级队列) 3. ConcurrentLinkedQueue, (基于链表的并发队列) 4. DelayQueue, (延期…...
大型Saas系统的权限体系设计(二)
X0 上期回顾 上文《大型Saas系统的权限体系设计(一)》提到2B的Saas系统的多层次权限体系设计的难题,即平台、平台的客户、客户的客户,乃至客户的客户的客户如何授权,这个可以通过“权限-角色-岗位”三级结构来实现。 但这个只是功能权限&am…...
HTML(四) -- 多媒体设计
目录 1. 视频标签 2. 音频标签 3. 资源标签(定义媒介资源 ) 1. 视频标签 属性值描述autoplayautoplay如果出现该属性,则视频在就绪后马上播放。controlscontrols表示添加标准的视频控制界面,包括播放、暂停、快进、音量等…...
设置苹果电脑vsode在新窗口中打开文件
0、前言 最近切换到mac电脑工作,又得重新安装一些工具软件并设置。虽然这些设置并表示啥复杂的设置,但是久了不设置还是会忘记。于是记录之,也希望给能帮助到需要的人。 我们使用vscode阅读或者编辑文件时,有时候希望同时打开多…...
第二章创建模式—单例设计模式
文章目录 单例模式的结构如何控制只有一个对象呢怎么设计这个类的内部对象外部怎么访问 单例模式的主要有以下角色 单例模式的实现饿汉式 1:静态变量饿汉式 2:静态代码块懒汉式 1:线程不安全懒汉式 2:线程安全—方法级上锁懒汉式 …...
数据结构学习记录——堆的插入(堆的结构类型定义、最大堆的创建、堆的插入:堆的插入的三种情况、哨兵元素)
目录 堆的结构类型定义 最大堆的创建 堆的插入 堆的插入的三种情况 代码实现 哨兵元素 堆的结构类型定义 #define ElementType int typedef struct HNode* Heap; /* 堆的类型定义 */ struct HNode {ElementType* Data; /* 存储元素的数组 */int Size; /* 堆中…...
netperf测试
netperf测试 目录 批量网络流量性能测试 TCP_STREAM测试UDP_STREAM 测试请求/应答网络流量测试 TCP_RR TCP_CRR Netperf 是一个网络性能测试工具,它可以测试网络协议栈的性能,例如TCP和UDP协议。Netperf可以测量网络吞吐量、延迟和CPU利用率等指标。…...
ORACLE常用语句
1.修改用户密码 alter user 用户名 identified by 新密码; 2.表空间扩容 1.增加数据文件 alter tablespace AA add datafile ‘DATA’ size 20G autoextend off; 2.修改数据文件大小 ALTER DATABASE DATAFILE ‘E:\ORACLE\PRODUCT\10.2.0\ORADATA\aa\aa.DBF’ RESIZE 400M;…...
[论文笔记]C^3F,MCNN:图片人群计数模型
(万能代码)CommissarMa/Crowd_counting_from_scratch 代码:https://github.com/CommissarMa/Crowd_counting_from_scratch (万能代码)C^3 Framework开源人群计数框架 科普中文博文:https://zhuanlan.zhihu.com/p/65650998 框架网址:https…...
HCIP-7.2VLAN间通信单臂、多臂、三层交换方式学习
VLAN间通信单臂、多臂、三层交换方式学习 1、单臂路由2、多臂路由3、三层交换机的SVI接口实现VLAN间通讯3.1、VLANIF虚拟接口3.2、VLAN间路由3.2.1、单台三层路由VLAN间通信,在一台三层交换机内部VLAN之间直连。3.2.2、两台三层交换机的之间的VLAN通信。3.2.3、将物…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
