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上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/67907.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode--HOT100题(47)

目录 题目描述&#xff1a;105. 从前序与中序遍历序列构造二叉树&#xff08;中等&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;105. 从前序与中序遍历序列构造二叉树&#xff08;中等&#xff09; 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preo…

基于Vgg-Unet模型自动驾驶场景检测

1.VGG VGG全称是Visual Geometry Group属于牛津大学科学工程系&#xff0c;其发布了一些列以VGG开头的卷积网络模型&#xff0c;可以应用在人脸识别、图像分类等方面,VGG的输入被设置为大小为224x244的RGB图像。为训练集图像上的所有图像计算平均RGB值&#xff0c;然后将该图像…

系统错误码指示确立+日志模块手动配置

1&#xff0c;系统错误码指示确立 对于前后端分离的系统设计中&#xff0c;后端建立错误码指示对于前端非常重要可以指示错误存在地方&#xff1b;以用户注册为例&#xff1b; public interface SystemCode{int SYSTEM_USER_ERROR_ADD_FAIL 10000;int SYSTEM_USER_INFO_ADD …

Miniconda3环境迁移

问题&#xff1a; conda之前安装的默认路径空间满了没法进行安装&#xff0c;为此将其进行迁移&#xff0c;但是迁移之后报错 bash: /data/anaconda3/bin/conda: /home/anaconda3/bin/python: 坏的解释器: 没有那个文件或目录解决方案&#xff1a; 1、修改~/.bashrc中的环境…

B093-springsecurity整合jwt和RSA

目录 前后端分离后springsecurity核心filter的应用场景介绍JWT令牌的组成部分JWT案例导包TestJwt RSARsaUtilsTestRSA分析图 JWTRSA导包JwtUtilsTestRSAJWT 完善spring-security整合后且不连数据库的代码案例流程分析图 前后端分离后springsecurity核心filter的应用场景介绍 账…

Java设计模式:四、行为型模式-09:模板模式

文章目录 一、定义&#xff1a;模板模式二、模拟场景&#xff1a;模板模式三、改善代码&#xff1a;模板模式3.0 引入依赖3.1 工程结构3.2 模板模式结构图3.3 爬取商品生成海报实现3.3.1 HTTP获取连接类3.3.2 定义执行顺序的抽象类3.3.3 当当爬取抽象实现类3.3.4 京东爬取抽象实…

分享2款微课录制软件,保证让你满意!

“录微课用什么软件呀&#xff0c;真的服了&#xff0c;平台自带的录屏画质太差了&#xff0c;完全看不清讲的内容&#xff0c;而且音质也不是很好&#xff0c;大家有没有微课录制的软件推荐&#xff0c;谢谢啦” 随着教育方式的转型和技术的发展&#xff0c;微课程成为了一种…

422规范详解

概述&#xff1a; 全称为EIA-TIA-422-B&#xff0c;于1994年发布。 典型电路由一个发送器和N个接收器以及一个中断匹配电阻组成。 发送器&#xff1a; 差分输出电压值在2V~10V之间。 4.1.1 发送器输出阻抗 要求A/B之间的差分阻抗≤100Ω。 4.1.2 开路特性 要求差分电压≤…

从过滤器初识责任链设计模式

下面用的过滤器都是注解方式 可以使用非注解方式,就是去web.xml配置映射关系 上面程序的执行输出是 再加一个过滤器 下面来看一段程序 输出结果 和过滤器是否非常相识 但是上面这段程序存在的问题:在编译阶段已经完全确定了调用关系,如果你想改变他们的调用顺序或者继续添加一…

时序预测 | MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神经网络时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神…

淘宝API接口:提高电商运营效率与用户体验的利器(淘宝API接口使用指南)

淘宝API接口&#xff1a;提高电商运营效率与用户体验的利器 随着电商行业的快速发展&#xff0c;淘宝作为国内最大的电商平台之一&#xff0c;不断探索和创新&#xff0c;以满足不断变化的用户需求和商家需求。其中&#xff0c;淘宝API接口便是其创新的一个重要方面。本文将深…

【代码实现】DETR原文解读及代码实现细节

1 模型总览 宏观上来说&#xff0c;DETR主要包含三部分&#xff1a;以卷积神经网络为主的骨干网&#xff08;CNN Backbone&#xff09;、以TRM(Transformer)为主的特征抽取及交互器以及以FFN为主的分类和回归头&#xff0c;如DETR中build()函数所示。DETR最出彩的地方在于&…

[羊城杯 2020] easyphp

打开题目&#xff0c;源代码 <?php$files scandir(./); foreach($files as $file) {if(is_file($file)){if ($file ! "index.php") {unlink($file);}}}if(!isset($_GET[content]) || !isset($_GET[filename])) {highlight_file(__FILE__);die();}$content $_GE…

Spring 6.0和SpringBoot 3.0新特性

目录 主要更新内容是以下几个&#xff1a; AOT编译 Spring Native GraalVM SpringBoot3生成二进制可执行文件底层流程 主要更新内容是以下几个&#xff1a; A Java 17 baselineSupport for Jakarta EE 10 with an EE 9 baselineSupport for generating native images with…

【Sentinel】核心API-Entry与Context

文章目录 一、Entry1、Entry的声明2、使用API自定义资源3、基于SentinelResource注解标记资源 二、Context1、Context介绍2、Context的初始化3、AbstractSentinelInterceptor4、ContextUtil 一、Entry 1、Entry的声明 默认情况下&#xff0c;Sentinel会将controller中的方法作…

46、TCP的“三次握手”

在上一节中&#xff0c;TCP首部常用的几个选项&#xff0c;有些选项的参数就是在通信双方在建立TCP连接的时候进行确定和协商的。所以在学习过TCP报文首部之后&#xff0c;下面我们开始学习TCP的连接建立。 TCP的一个特点是提供可靠的传输机制&#xff0c;还有一个特点就是TCP…

Spring MVC 五 - DispatcherServlet初始化过程(续)

今天的内容是SpringMVC的初始化过程&#xff0c;其实也就是DispatcherServilet的初始化过程。 Special Bean Types DispatcherServlet委托如下一些特殊的bean来处理请求、并渲染正确的返回。这些特殊的bean是Spring MVC框架管理的bean、按照Spring框架的约定处理相关请求&…

leetcode56. 合并区间(java)

合并区间 题目描述贪心算法代码演示 题目描述 难度 - 中等 leetcode56. 合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好…

Elasticsearch 对比传统数据库:深入挖掘 Elasticsearch 的优势

当你为项目选择数据库或搜索引擎时&#xff0c;了解每个选项的细微差别至关重要。 今天&#xff0c;我们将深入探讨 Elasticsearch 的优势&#xff0c;并探讨它与传统 SQL 和 NoSQL 数据库的比较。 1. Elasticsearch简介 Elasticsearch 以强大的 Apache Lucene 库为基础&#…

算法通关村第9关【白银】| 二分查找与搜索树高频问题

基于二分查找的拓展问题 1.山脉数组的峰顶索引 思路&#xff1a;二分查找 山峰有三种状态&#xff1a;需要注意数组边界 1.顶峰&#xff1a;arr[mid]>arr[mid1]&&arr[mid]>arr[mid-1] 2.上坡&#xff1a;arr[mid]<arr[mid1] 3.下坡&#xff1a;arr[mid]…