Servlet属性、监听者和会话

news2024/11/18 8:46:12

 没有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 {

    @Override
    protected 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 {
    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        System.out.println("myAtt 添加到:" + event.getSession());
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        System.out.println("myAtt 移除");
    }
}

public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {

    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {
        System.out.println("添加session属性:" + event.getName() + ",其值为:" + event.getValue());
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent event) {
        System.out.println("删除session属性:" + event.getName() + ",其值为:" + event.getValue());
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent event) {
        System.out.println("替换属性:" + event.getName() + ",其值为:" + event.getValue());
    }

}

public class MyHttpSessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent event) {
        System.out.println("有个会话被创建了:" + event.getSession());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent event) {
        System.out.println("有个会话被销毁了:" + event.getSession());
    }
}

public class MyServletContextAttributeListener implements ServletContextAttributeListener {

    @Override
    public void attributeAdded(ServletContextAttributeEvent event) {
        System.out.println("添加上下文属性:" + event.getName() + ",其值为:" + event.getValue());
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent event) {
        System.out.println("删除上下文属性:" + event.getName() + ",其值为:" + event.getValue());
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent event) {
        System.out.println("替换上下文属性:" + event.getName() + ",其值为:" + event.getValue());
    }
}

public class MyServletContextListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent event) {
        System.out.println("上下文创建:" + event.getServletContext());
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        System.out.println("上下文销毁:" + event.getServletContext());
    }

}

public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {

    @Override
    public void attributeAdded(ServletRequestAttributeEvent event) {
        System.out.println("添加请求属性:" + event.getName() + ",其值为:" + event.getValue());
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent event) {
        System.out.println("删除请求属性:" + event.getName() + ",其值为:" + event.getValue());
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent event) {
        System.out.println("替换请求属性:" + event.getName() + ",其值为:" + event.getValue());
    }
}

public class MyServletRequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent event) {
        System.out.println("请求被销毁:" + event.getServletRequest());
    }

    @Override
    public void requestInitialized(ServletRequestEvent event) {
        System.out.println("请求初始化:" + event.getServletRequest());
    }
}

监听者 

public class ListenerServlet extends HttpServlet {

    @Override
    protected 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.coloradmin.cn/o/972190.html

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

相关文章

Text-to-SQL小白入门(四)指令进化大模型WizardLM

摘要 本文主要对大模型WizardLM的基本信息进行了简单介绍&#xff0c;展示了WizardLM取得的优秀性能&#xff0c;分析了论文的核心——指令进化方法。 论文概述 基本信息 英文标题&#xff1a;WizardLM: Empowering Large Language Models to Follow Complex Instructions中…

【实践篇】Redis使用规范清单详解

Redis 使用规范清单详解 文章目录 Redis 使用规范清单详解0. 前言参考资料 1. 键值对使用规范1. Key的命名规范2. 避免使用 bigkey2.1. "bigkey"的导致的问题2.2 避免"bigkey"问题解决方法2.2 1. 数据分片2.2.2. 数据压缩 3. 使用高效序列化方法和压缩方法…

jmeter 计数器Counter

计数器可以用于生成动态的数值或字符串&#xff0c;以模拟不同的用户或数据。 计数器通常与用户线程组结合使用&#xff0c;以生成不同的变量值并在测试中应用。以下是计数器的几个常用属性&#xff1a; 变量前缀&#xff08;Variable Name Prefix&#xff09;&#xff1a;定义…

C语言中结构体和位段的一些知识

一、结构体 struct stu {char name[20];//20//对齐数为8int age;//4//两个数中最大对齐数为8&#xff0c;而24又是8的整数倍 }; int main () {printf("%d\n", sizeof(struct stu));//只有vs中有对齐数为8&#xff0c;gcc没有对齐数&#xff0c;对齐数为成员变量自…

【MySQL】MySQL8.0安装教程

下载 MySQL官网下载安装包 安装 1、双击安装程序开始安装 2、选择安装类型 选Server only&#xff08;只安装mysql&#xff09;&#xff0c;然后点击“next”。 3、检测需要的安装&#xff0c; 直接点击Execute开始安装 4、点击next 5、点击next 6、next 7、密码验证方式&a…

EXCEL 中find,if and,if or

接上一篇sql中find函数的作用&#xff0c;由于工作需求是用帆软做报表&#xff0c;他的一些代码不仅有js&#xff0c;sql中的还有一些excel的相关知识&#xff0c;故作整理。 FIND() excel中的find原理和sql中相似&#xff0c;具体可查看 SQL函数 $FIND_Yangshiwei....的博客…

SAP 邮件发送配置

SICF激活服务SCOT邮箱发送配置 具体步骤如下&#xff1a; 1. SICF激活服务 进入事务码&#xff1a; SCIF 选中SAPconnect,右击选中激活SMT机&#xff0c;进行激活 2. SCOT配置邮箱发送设置 进入事务码&#xff1a; SCOT 点开业务通信管理-》设置-》SMTP连接-》出站信息-》…

vscode新建vue3文件模板

输入快捷新建的名字 enter 确认后在文件中输入以下内容 {// Place your snippets for vue here. Each snippet is defined under a snippet name and has a prefix, body and// description. The prefix is what is used to trigger the snippet and the body will be expand…

【计算机网络】 静态库与动态库

文章目录 静态库实践使用方法总结 动态库实践使用方法总结 静态库与动态库的优缺点静态库优点缺点 动态库缺点优点 库有两种&#xff1a;静态库&#xff08;.a、.lib&#xff09;和动态库&#xff08;.so、.dll&#xff09;。所谓静态、动态是指链接。静态库是将整个库文件都拷…

Github 下载指定文件夹(git sparse-checkout)

比如要下载这里的 data_utils 步骤 1、新建空文件夹&#xff0c;并进入新建的空文件夹。 2、git init 初始化 3、git remote add origin 添加远程仓库 4、git config core.sparsecheckout true 允许稀疏检出 5、git sparse-checkout set 设置需要拉取的文件夹&#xff08;可…

Lite transformer

图片以及思想来源请参考论文 Lite Transformer with Long-Short Range Attention 瓶颈结构&#xff08;bottleneck&#xff09;是否真的有效 注意力机制被广泛应用在诸多领域&#xff0c;包括自然语言处理&#xff0c;图像处理和视频处理。它通过计算所有输入元素的点积来建模…

idea 无法识别maven的解决

问题描述 从git拉取代码或者修改文件夹以后&#xff0c;整个项目所有依赖爆红无法通过修改或者重新加载maven解决版本为idea 2021 问题定位 maven的版本太高&#xff0c;而idea的般本太低&#xff0c;导致识别的时候稳定性差 解决 使用idea原生的maven版本 选择已捆绑的m…

Tribon二次开发-tbwautodraw

在Assembly模块中,通过设置和生成,可以在手动的基础上自动生成组立装配图。 1、设置视向,根据组立的具体情况选择,一般横向结构,是向船首看,纵向结构向左舷看,水平结构向下看。 2、在组立节点上右键,选项“Generate Assembly Drawing…” 确保图框A4L_…

无涯教程-JavaScript - DAYS函数

描述 DAYS函数返回两个日期之间的天数。 语法 DAYS (end_date, start_date)争论 Argument描述Required/OptionalEnd_dateStart_date and End_date are the two dates between which you want to know the number of days.RequiredStart_dateStart_date and End_date are th…

C# 基础面试题(万字)

1.选择题 1. 简述下面选项能够捕获运算溢出的异常类型的有 &#xff1f; A)Exception B)SystemException C)ArithmeticException D)OverflowException 试题回答&#xff1a;AD 2. 程序员可使用&#xff08;&#xff09;语句以程序方式引发异常 &#xff1f; A)run B)try C)th…

并发编程的故事——JUC

JUC 文章目录 JUC一、Semaphore二、CountDownLatch三、线程安全类 一、Semaphore 为什么需要用到Semaphore? 限流 Semaphore的场景&#xff1f; 秒杀商品的时候&#xff0c;不能够让那些没有秒杀成功的线程进入&#xff0c;只有占了坑位的才可以使用&#xff0c;这里可以用re…

Myvatis关联关系映射与表对象之间的关系

目录 一、关联关系映射 1.1 一对一 1.2 一对多 1.3 多对多 二、处理关联关系的方式 2.1 嵌套查询 2.2 嵌套结果 三、一对一关联映射 3.1 建表 ​编辑 3.2 配置文件 3.3 代码生成 3.4 编写测试 四、一对多关联映射 五、多对多关联映射 六、小结 一、关联关系映射 …

现货黄金代理好吗?

做黄金代理这个职业好吗&#xff1f;从目前的市场现状来看&#xff0c;其实做黄金代理很不错的。在股票市场中&#xff0c;投资者只能通过买涨进盈利&#xff0c;所以当市场行情不好的时候&#xff0c;股票经纪人的业务将很难展开&#xff0c;而现货黄金投资者不一样&#xff0…

mac 安装java1.8

1、下载jdk1.8 https://www.oracle.com/java/technologies/downloads/#java8-mac 2、 安装jdk1.8 一路默认&#xff0c;安装后的位置在这儿。 /Library/Java/JavaVirtualMachines/jdk-1.8.jdk 3、配置环境 打开终端&#xff0c;输入命令 sudo vim /etc/profile 添加以下配…

经管博士科研基础【19】齐次线性方程组

1. 线性方程组 2. 非线性方程组 非线性方程,就是因变量与自变量之间的关系不是线性的关系,这类方程很多,例如平方关系、对数关系、指数关系、三角函数关系等等。求解此类方程往往很难得到精确解,经常需要求近似解问题。相应的求近似解的方法也逐渐得到大家的重视。 3. 线…