实验六~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、将物…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...