当前位置: 首页 > news >正文

Servlet属性、监听者和会话

 没有servlet能单独存在。在当前的现代Web应用中,许多组件都是在一起协作共同完成一个目标。怎么让这些组件共享信息?如何隐藏信息?怎样让信息做到线程安全?

1 属性和监听者

1.1 初始化

容器初始化一个servlet时,会为这个servlet建一个唯一的ServletConfig。容器从web.xml 配置文件中“读出”servlet初始化参数,并把这些参数交给ServletConfig。然后把ServletConfig传递给servlet的init()方法。

一旦参数置于ServletConfig中,就不会再读了,除非重写部署了servlet。

1.1.1 上下文初始化参数

上下文初始化参数与servlet初始化参数很类似,只不过上下文参数对整个Web应用可用,而不只针对一个servlet。

public class InitServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletConfig servletConfig = getServletConfig();String servletName = servletConfig.getInitParameter("servletName");ServletContext servletContext = getServletContext();String contextName = servletContext.getInitParameter("contextName");resp.setCharacterEncoding("gbk");PrintWriter writer = resp.getWriter();writer.println("servlet初始化参数:" + servletName);writer.println("上下文初始化参数:" + contextName);writer.close();}
}
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"version="2.4"><servlet><servlet-name>initServlet</servlet-name><servlet-class>servlet.InitServlet</servlet-class><init-param><param-name>servletName</param-name><param-value>initServlet</param-value></init-param></servlet><context-param><param-name>contextName</param-name><param-value>day01</param-value></context-param><servlet-mapping><servlet-name>initServlet</servlet-name><url-pattern>/init</url-pattern></servlet-mapping></web-app>

web.xml 

1.2 监听者

接口

使用场景

ServletContextAttributeListener

监听Web应用上下文中是否增加、删除或替换了一个属性。

HttpSessionListener

监听会话的创建。

ServletRequestListener

用户请求监听。

ServletRequestAttributeListener

监听请求增加、删除或替换属性。

HttpSessionBindingListener

属性类对象在绑定到一个会话或从会话删除时触发给属性类对象。

HttpSessionAttributeListener

监听会话增加、删除或替换属性。

ServletContextListener

监听Web应用上下文创建或销毁。

HttpSessionActivationListener

监听会话迁移到另一个JVM。

表 servlet常见的8种监听者

public class MyAtt implements HttpSessionBindingListener {@Overridepublic void valueBound(HttpSessionBindingEvent event) {System.out.println("myAtt 添加到:" + event.getSession());}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {System.out.println("myAtt 移除");}
}public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {@Overridepublic void attributeAdded(HttpSessionBindingEvent event) {System.out.println("添加session属性:" + event.getName() + ",其值为:" + event.getValue());}@Overridepublic void attributeRemoved(HttpSessionBindingEvent event) {System.out.println("删除session属性:" + event.getName() + ",其值为:" + event.getValue());}@Overridepublic void attributeReplaced(HttpSessionBindingEvent event) {System.out.println("替换属性:" + event.getName() + ",其值为:" + event.getValue());}}public class MyHttpSessionListener implements HttpSessionListener {@Overridepublic void sessionCreated(HttpSessionEvent event) {System.out.println("有个会话被创建了:" + event.getSession());}@Overridepublic void sessionDestroyed(HttpSessionEvent event) {System.out.println("有个会话被销毁了:" + event.getSession());}
}public class MyServletContextAttributeListener implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {System.out.println("添加上下文属性:" + event.getName() + ",其值为:" + event.getValue());}@Overridepublic void attributeRemoved(ServletContextAttributeEvent event) {System.out.println("删除上下文属性:" + event.getName() + ",其值为:" + event.getValue());}@Overridepublic void attributeReplaced(ServletContextAttributeEvent event) {System.out.println("替换上下文属性:" + event.getName() + ",其值为:" + event.getValue());}
}public class MyServletContextListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent event) {System.out.println("上下文创建:" + event.getServletContext());}@Overridepublic void contextDestroyed(ServletContextEvent event) {System.out.println("上下文销毁:" + event.getServletContext());}}public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {@Overridepublic void attributeAdded(ServletRequestAttributeEvent event) {System.out.println("添加请求属性:" + event.getName() + ",其值为:" + event.getValue());}@Overridepublic void attributeRemoved(ServletRequestAttributeEvent event) {System.out.println("删除请求属性:" + event.getName() + ",其值为:" + event.getValue());}@Overridepublic void attributeReplaced(ServletRequestAttributeEvent event) {System.out.println("替换请求属性:" + event.getName() + ",其值为:" + event.getValue());}
}public class MyServletRequestListener implements ServletRequestListener {@Overridepublic void requestDestroyed(ServletRequestEvent event) {System.out.println("请求被销毁:" + event.getServletRequest());}@Overridepublic void requestInitialized(ServletRequestEvent event) {System.out.println("请求初始化:" + event.getServletRequest());}
}

监听者 

public class ListenerServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setAttribute("reqAtt","hello req");req.getSession().setAttribute("sessionAtt", "hello session");req.getSession().setAttribute("binding",new MyAtt());getServletContext().setAttribute("contextAtt", "hello context");}
}

 

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"version="2.4"><servlet><servlet-name>listenerServlet</servlet-name><servlet-class>servlet.ListenerServlet</servlet-class></servlet><servlet-mapping><servlet-name>listenerServlet</servlet-name><url-pattern>/listener</url-pattern></servlet-mapping><listener><listener-class>listener.MyHttpSessionAttributeListener</listener-class></listener><listener><listener-class>listener.MyHttpSessionListener</listener-class></listener><listener><listener-class>listener.MyServletContextAttributeListener</listener-class></listener><listener><listener-class>listener.MyServletContextListener</listener-class></listener><listener><listener-class>listener.MyServletRequestAttributeListener</listener-class></listener><listener><listener-class>listener.MyServletRequestListener</listener-class></listener></web-app>

web.xml 

2 会话管理

Web服务器没有短期记忆。

HttpSession对象可以保存跨同一个客户多个请求的会话状态,即与一个特定客户的整个会话期间,HttpSession会持久存储。对于会话期间客户做的所有请求,都可以用HttpSession存取。

2.1 容器几乎做cookie的所有工作

除了必须告诉容器创建或使用一个会话,其他工作,比如生成会话ID、创建新的cookie对象、把会话ID放到cookie中、把cookie设置为响应的一部分以及从请求中的cookie得到会话ID,将这个会话ID与一个现有会话匹配等工作都是由容器完成。

HttpSession session = request.getSession(); // 在响应中发送一个会话cookie

执行完上面后,容器会负责余下的事情,你什么也不用做。

HttpSession session = request.getSession(); // 从请求得到会话id。

执行完上面后,容器会负责余下的事情(找到与该ID匹配的会话,没有则创建一个新会话)。

图 执行request.getSession()后的响应与请求

当cookie被禁时,URL重写是一条后路:如果客户端不接受cookie,可以把URL重写作为一条后路。当然,在实际开发中,这种方法很少使用。

2.2 删除会话

删除会话有两种方式(不包括结束应用):

1)设置超时时间,setMaxInactiveInterval() 指定对于这个会话客户请求的最大间隔时间(秒)。

也可以在web.xml中配置,单位是分钟

<session-config>

      <session-timeout>15<session-timeout>

</session-config>

2)结束会话,invalidate()

2.3 会话迁移

在部署分布式Web应用时,容器可能会负载均衡,取得客户的请求,把请求发送到多个JVM上。例如,每次客户请求时,有可能到达同一个servlet到不同实例。

只有HttpSession对象(及其属性)会从一个VM移到另一个VM。

每个VM中有一个ServletContext,每个VM上的每个servlet有一个ServletConfig。但是对于每个Web应用的一个给定会话ID,只有一个HttpSession对象,而无论应用分布在多少个VM上。

相关文章:

Servlet属性、监听者和会话

没有servlet能单独存在。在当前的现代Web应用中&#xff0c;许多组件都是在一起协作共同完成一个目标。怎么让这些组件共享信息&#xff1f;如何隐藏信息&#xff1f;怎样让信息做到线程安全&#xff1f; 1 属性和监听者 1.1 初始化 容器初始化一个servlet时&#xff0c;会为…...

Gin学习记录2——路由

路由 一. 常规路由二. 动态路由三. 带参数的路由3.1 GET3.2 POST3.3 绑定 四. 简单的路由组五. 文件分组 一. 常规路由 package mainimport ("net/http""github.com/gin-gonic/gin" )func index(ctx *gin.Context) {ctx.String(http.StatusOK, "Hell…...

《计算机算法设计与分析》第一章:算法概述

第一章 算法概述 1.1 算法复杂性分析 公共标准&#xff1a;渐进时间复杂度 &#xff08;1&#xff09;大O表示法&#xff1a; 例如&#xff1a; 大O表示法和前面的最坏时间复杂度的区别在于&#xff1a;大O表示法表示的更为简洁&#xff0c; 而最坏时间复杂度相对就比较繁琐&am…...

华为数通方向HCIP-DataCom H12-821题库(单选题:201-220)

第201题 BGP 协议用​​ beer default-route-advertise​​ 命令来给邻居发布缺省路由,那么以下关于本地 BGP 路由表变化的描述&#xff0c;正确的是哪一项? A、在本地 BGP 路由表中生成一条活跃的缺省路由并下发给路由表 B、在本地 BGP 路由表中生成一条不活跃的缺省路由&…...

使用ELK收集解析nginx日志和kibana可视化仪表盘

文章目录 ELK生产环境配置filebeat 配置logstash 配置 kibana仪表盘配置配置nginx转发ES和kibanaELK设置账号和密码 ELK生产环境配置 ELK收集nginx日志有多种方案&#xff0c;一般比较常见的做法是在生产环境服务器搭建filebeat 收集nginx的文件日志并写入到队列&#xff08;k…...

【Sentinel】ProcessorSlotChain处理器插槽链与Node

文章目录 1、Sentinel的基本概念2、ProcessorSlotChain3、Node 1、Sentinel的基本概念 Sentinel实现限流、隔离、降级、熔断等功能&#xff0c;本质要做的就是两件事情&#xff1a; 统计数据&#xff1a;统计某个资源的访问数据&#xff08;QPS、RT等信息&#xff09;规则判断…...

数据库管理系统(DBMS)的事务四大特性(ACID)以及事务的四种隔离级别

一、什么是ACID&#xff1f; ACID是原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isolation&#xff09;和持久性&#xff08;Durability&#xff09; 的缩写&#xff0c;是在可靠数据库管理系统&#xff08;DBMS&…...

leetcode 234. 回文链表

2023.9.5 本题先将链表的节点值移到数组中&#xff0c;再用双指针去判断该数组是否为回文的即可。 代码如下&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* …...

Scala集合继承体系图

Scala集合简介 1&#xff09; Scala 的集合有三大类&#xff1a;序列 Seq、集Set、映射 Map&#xff0c;所有的集合都扩展自 Iterable特质。 2&#xff09; 对于几乎所有的集合类&#xff0c;Scala 都同时提供了可变和不可变的版本&#xff0c;分别位于以下两个包 不可变集合…...

《Go 语言第一课》课程学习笔记(十五)

并发 Go 的并发方案&#xff1a;goroutine 并行&#xff08;parallelism&#xff09;&#xff0c;指的就是在同一时刻&#xff0c;有两个或两个以上的任务&#xff08;这里指进程&#xff09;的代码在处理器上执行。 并发不是并行&#xff0c;并发关乎结构&#xff0c;并行关…...

练习 Qt 实时显示鼠标坐标位置

Qt 入门实战教程&#xff08;目录&#xff09; 前驱课程 本文是文章 Qt鼠标点击事件处理&#xff1a;显示鼠标点击位置&#xff08;完整示例&#xff09; 的一个作业&#xff08;下文称之为“前驱课程”&#xff09;。 前驱课程中&#xff0c;我们完整的展示了如何在QtCreat…...

Leetcode130. 被围绕的区域

Every day a Leetcode 题目来源&#xff1a;130. 被围绕的区域 本题给定的矩阵中有三种元素&#xff1a; 字母 X&#xff1b;被字母 X 包围的字母 O&#xff1b;没有被字母 X 包围的字母 O。 本题要求将所有被字母 X 包围的字母 O都变为字母 X &#xff0c;但很难判断哪些 …...

6.xpath的基本使用

xpath是python做数据解析的库 目录 1 安装 2 解析本地的html文件 2.1 只有一个标签的情况 2.2 有多个标签的情况 3 解析网上的页面 4 xpath表达式 4.1 绝对路径 4.2 两个斜杠表示中间隔了0级或多级 4.3 通过属性查找 4.4 通过索引查找 4.5 获取文本内容…...

uniapp组件库总结笔记

uView-ui uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架 优点&#xff1a;整体样式风格不错 缺点&#xff1a;不支持vue3&#xff08;可以使用社区维护的uview-plus uview-plus 3.0 - 全面兼容nvue的uni-app生态框架 - uni-app UI框架&#xff09; uni-u…...

day-42 代码随想录算法训练营 动态规划 part 04

416.分割等和子集 分析&#xff1a;需要总和能分成两半&#xff0c;并且有子集能装满一半 思路&#xff1a; 1.dp存储&#xff1a;容量为j时装入的最大数值和dp[j]2.dp[j]max(dp[j],dp[j-nums[i]]nums[i]) 3.全部初始化为04.遍历顺序&#xff1a;外层遍历元素&#xff0c;内…...

Swift 周报 第三十六期

文章目录 前言新闻和社区消息称苹果公司和印度财政部官员磋商&#xff0c;扩大在印度的制造产能iPhone 15 Pro 机型新增泰坦灰iPhone 15 全系配 USB-C 苹果拒绝接口和安卓互通 提案正在审查的提案 Swift论坛推荐博文话题讨论关于我们 前言 本期是 Swift 编辑组整理周报的第三十…...

手写Mybatis:第19章-二级缓存

文章目录 一、目标&#xff1a;二级缓存二、设计&#xff1a;二级缓存三、实现&#xff1a;二级缓存3.1 工程结构3.2 二级缓存类图3.3 二级缓存队列3.3.1 FIFI缓存策略3.3.2 事务缓存3.3.3 事务管理3.3.4 修改一级缓存 3.4 缓存执行器3.4.1 执行器接口3.4.2 执行器抽象基类3.4.…...

Alibaba Canal 使用记录

项目中使用 canal 来同步数据到 Elasticsearch, 遇到很多问题&#xff0c;做一下记录&#xff1a; 版本问题&#xff1a; 1. 解析binlog出错 &#xff0c;表现为 limit excceed&#xff1a;xx 目前使用 mariadb 10.9.7/10.10.6 canal 1.1.6 hotfix &#xff0c;在这个版本组…...

GIT实战篇,教你如何使用GIT可视化工具

系列文章目录 手把手教你安装Git&#xff0c;萌新迈向专业的必备一步 GIT命令只会抄却不理解&#xff1f;看完原理才能事半功倍&#xff01; 快速上手GIT命令&#xff0c;现学也能登堂入室 GIT实战篇&#xff0c;教你如何使用GIT可视化工具 系列文章目录一、GIT有哪些常用工具…...

lv3 嵌入式开发-4 linux shell命令(文件搜索、文件处理、压缩)

目录 1 查看文件相关命令 1.1 常用命令 1.2 硬链接和软链接 2 文件搜索相关命令 2.1 查找文件命令 2.2 查找文件内容命令 2.3 其他相关命令 3 文件处理相关命令 3.1 cut 3.2 sed 过滤 3.3 awk 匹配 4 解压缩相关命令 4.1 解压缩文件的意义 4.2 解压缩相关命令 1 …...

MouseOverShapeBox

MouseOverShapeBox MouseOverShapeBox 源码详解 - 鼠标悬停高亮标注框 这是一个增强版图像标注控件&#xff0c;当鼠标移动到形状上时&#xff0c;会高亮显示该形状。类似于图片标注工具中鼠标悬停时边框变色的效果。&#x1f4c4; 文件头部&#xff08;版权信息&#xff09; /…...

如何高效管理百度网盘文件:自动化批量转存与分享的完整指南

如何高效管理百度网盘文件&#xff1a;自动化批量转存与分享的完整指南 【免费下载链接】BaiduPanFilesTransfers 百度网盘批量转存、分享和检测工具 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduPanFilesTransfers 在数字资源日益丰富的今天&#xff0c;百度网盘…...

NXOpen 方式创建拉伸和预览

//用户代码 #include "ExtrudewithPreview.hpp" #include "NXOpen/Body.hxx" #include "NXOpen/Direction.hxx" #include "NXOpen/DisplayableObject.hxx" #include "NXOpen/DisplayModification.hxx" #include "…...

深度解析ViGEmBus:如何高效构建Windows内核级游戏控制器模拟框架

深度解析ViGEmBus&#xff1a;如何高效构建Windows内核级游戏控制器模拟框架 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus ViGEmBus是一款基于Windows内核…...

CLIP-GmP-ViT-L-14GPU算力适配:ViT-L模型显存占用分析与推理加速实践

CLIP-GmP-ViT-L-14 GPU算力适配&#xff1a;ViT-L模型显存占用分析与推理加速实践 1. 引言 当你拿到一个像 CLIP-GmP-ViT-L-14 这样强大的视觉-语言模型时&#xff0c;第一反应可能是兴奋——它拥有接近90%的ImageNet准确率&#xff0c;能精准理解图片和文字的关系。但当你尝…...

像素语言·跨维传送门参数详解:Hunyuan-MT-7B引擎温度/长度/对齐策略调优指南

像素语言跨维传送门参数详解&#xff1a;Hunyuan-MT-7B引擎温度/长度/对齐策略调优指南 1. 工具概览与核心价值 像素语言跨维传送门(Pixel Language Portal)是基于Tencent Hunyuan-MT-7B引擎构建的创新翻译工具&#xff0c;它将传统翻译体验重构为16-bit像素冒险风格。不同于…...

Qwen3.5-9B-AWQ-4bit效果展示:高清截图OCR、场景描述、主体识别实测集

Qwen3.5-9B-AWQ-4bit效果展示&#xff1a;高清截图OCR、场景描述、主体识别实测集 1. 模型能力概览 Qwen3.5-9B-AWQ-4bit是一款基于量化技术的多模态视觉理解模型&#xff0c;能够同时处理图像和文本输入&#xff0c;输出高质量的中文分析结果。这个4bit量化版本在保持核心能…...

AI手势识别与追踪:Android端5分钟快速集成教程(附彩虹骨骼效果)

AI手势识别与追踪&#xff1a;Android端5分钟快速集成教程&#xff08;附彩虹骨骼效果&#xff09; 1. 引言 1.1 手势识别的价值 想象一下&#xff0c;不用触碰屏幕就能控制手机——这不是科幻电影&#xff0c;而是AI手势识别技术带来的真实体验。从智能家居控制到AR游戏交互…...

宝塔部署前后端时,配置域名与ssl证书

创建文件夹1.后端部署部署之后点击设置这步骤最关键# HTTP反向代理相关配置开始 >>>location ~ /purge(/.*) {proxy_cache_purge cache_one $Host$request_uri$is_args$args;}location / {proxy_pass http://127.0.0.1:8773;proxy_set_header Host $Host:$server_port…...

weibo-rss:让微博内容主动找到你的高效订阅工具

weibo-rss&#xff1a;让微博内容主动找到你的高效订阅工具 【免费下载链接】weibo-rss &#x1f370; 把喜欢的微博转为 RSS 订阅源 项目地址: https://gitcode.com/gh_mirrors/we/weibo-rss 在信息爆炸的时代&#xff0c;我们每天要处理大量碎片化内容。微博作为主流社…...