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.hqwc.cn/news/97787.html

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

相关文章

【HTML5高级第一篇】Web存储 - cookie、localStorage、sessionStorage

文章目录 一、数据存储1.1 cookie1.1.1 概念介绍1.1.2 存储与获取1.1.3 方法的封装1.1.4 总结 1.2 localstorage 与 sessionstorage1.2.1 概述1.2.2 操作数据的属性或方法1.2.3 案例-提交问卷1.2.4 Web Storage带来的好处 附录&#xff1a;1. HTML5提供的数据持久化技术&#x…

算法 数据结构 双向环形链表 手撸环形链表 环形链表实现容器 环形链表添加修改删除获取大小 环形链表实现自定义容器 手撸容器 双向环形哨兵链表 数据结构(六)

1. 环形链表&#xff1a; 2. 建议先不要看我写得自己先实现下&#xff0c;只将Node内部类复制自己命名得容器内&#xff0c; 实现方法&#xff1a; a. add方法&#xff08;添加到头部&#xff0c;尾部添加&#xff0c;指定位置添加&#xff09; b. get方法&#xff08;获取首部…

基于costas环的载波同步系统matlab性能仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ............................................................................ I_Dataroun…

Word转为PDF后图片模糊怎么办?Word转为PDF的技巧介绍

将Word文档转为PDF是我们日常办公和文档处理中常见的需求。PDF格式的优势在于跨平台兼容性、保留原始格式、文档保护以及方便共享和分发等方面。本文将探讨Word转为PDF后图片模糊怎么办?Word转为PDF的技巧有哪些?通过这些问题的答案&#xff0c;可以帮助您更好的利用文件转换…

AJAX学习笔记5同步与异步理解

AJAX学习笔记4解决乱码问题_biubiubiu0706的博客-CSDN博客 示例 前端代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>演示AJAX同步和异步</title> </head> <body> <script…

Nginx跨域问题的解决方法

项目场景&#xff1a; Web前端开发经常会遇到跨域访问&#xff0c;如果没有办法让后台开放访问域&#xff0c;调用接口就会被浏览器拦截。解决跨域问题的方案&#xff0c;可以搭建一个后台服务做中间转发&#xff0c;也可以用nginxhttps://so.csdn.net/so/search?qnginx转发。…

【业务功能篇96】微服务-springcloud-springboot-认证服务-登录注册功能-Auth2.0-分布式session

5.登录功能 通过最基础的登录操作来完成登录处理 登录页面处理 认证服务的处理 /*** 注册的方法* return*/PostMapping("/login")public String login(LoginVo loginVo , RedirectAttributes redirectAttributes){R r memberFeginService.login(loginVo);if(r.getC…

手写Mybatis:第10章-使用策略模式,调用参数处理器

文章目录 一、目标&#xff1a;参数处理器二、设计&#xff1a;参数处理器三、实现&#xff1a;参数处理器3.1 工程结构3.2 参数处理器关系图3.3 入参数校准3.4 参数策略处理器3.4.1 JDBC枚举类型修改3.4.2 类型处理器接口3.4.3 模板模式&#xff1a;类型处理器抽象基类3.4.4 类…

C#FreeSql分库分表

using FreeSql; using FreeSql.DataAnnotations;namespace FreeSqlMaster {internal class Program{static IFreeSql freeSql null;static void Main(string[] args){// 读写分离// FreeSql 实现了第3种方案&#xff0c;支持一个【主库】多个【从库】&#xff0c;【从库】的查…

在OpenStack私有云上安装配置虚拟机

文章目录 零、学习目标一、登录大数据实训云二、创建网络三、创建路由四、添加接口五、创建端口六、添加安全组规则七、创建实例&#xff08;一&#xff09;实例规划&#xff08;二&#xff09;创建实例 - ied&#xff08;三&#xff09;创建实例 - master、slave1与slave2&…

字节二面:如果高性能渲染十万条数据?

前言 最近博主在字节面试中遇到这样一个面试题&#xff0c;这个问题也是前端面试的高频问题&#xff0c;作为一名前端开发工程师&#xff0c;我们虽然可能很少会遇到后端返回十万条数据的情况&#xff0c;但是了解掌握如何处理这种情况&#xff0c;能让你对前端性能优化有更深的…

Ubuntu tmux 默认安装 快捷键

安装 sudo apt install tmux 启动tmux tmux 注意下方已显示[0] 0:bash 左右分屏 依次输入两组快捷键&#xff1a;Ctrlb, Shift5 即:% 上下分屏 依次输入两组快捷键&#xff1a;Ctrlb, Shift 即:" 切换窗口&#xff08;注意&#xff1a;鼠标点击没有切换效果&#x…