(十四)Servlet教程——Servlet中HttpSession的使用

        除了使用Cookie,Web应用程序中还经常使用Session来记录客户端状态。Session是服务器端使用的一种记录客户端状态的机制,相应地也增加了服务器的存储压力。

1. 什么是Session

        Session是另外一种记录客户端状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。Session是一种连接状态变量,客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要客户档案表就可以了。

2. Session的使用

        Session对应的类为javax.servlet.http.HttpSession类。每个来访者对应一个Session对象,所有该客户的状态信息都保存在这个Session对象里。Session是在客户端第一次请求服务器的时候创建的。Session也只有key-value的属性对,Session是一种集合型变量,可以存储多个key-value类型值对,key为字符串类型,value可以为任何对象类型。

通过getAttribute(String key)和setAttribute(String key,Object value)方法读写客户状态信息。Servlet通过request.getSession()方法获取该客户的Session。

        当多个客户端执行程序时,服务器会保存多个客户端的Session。获取Session的时候也不需要声明获取谁的Session。Session机制决定了当前客户只会获取到自己的Session,而不会获取到别人的Session。各客户的Session也彼此独立,互不可见。

        Session的使用比Cookie方便,但是过多的Session存储在服务器内存中,会对服务器造成压力。

3. Session的生命周期和有效期

        Session保存在服务器端,服务器一般把Session放在内存里。每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时就可能会导致内存溢出,因此,Session里的信息应该尽量精简。

        Session在用户第一次访问服务器时自动创建。需要注意的是,只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。如果尚未生成Session,也可以使用request.getSession(true)强制生成Session。

        Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户访问服务器一次,无论是否读写Session,服务器都认为该用户的Session活跃了一次。

        由于有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把一段时间内没有活跃的Session从内存中删除。这段时间就是Session的超时时间。如果超过了超时时间没有访问过服务器,Session就自动失效了。

        Session的超时时间为maxInactiveInterval属性,可以通过对应的getMaxInactiveInterval()获取,通过setMaxInactiveInterval(long interval)修改。

        Session的超时时间也可以在web.xml中修改。另外,通过调用Session的invalidate()方法也可以使Session失效。

        Tomcat中Session的默认超时时间为30分钟。通过setMaxInactiveInterval(int seconds)修改超时时间。

        可以修改web.xml改变Session的默认超时时间。例如修改为60分钟。

        web.xml文件存放路径在Tomcat目录的conf文件夹中。

 <session-config>

    <session-timeout>60</session-timeout>

</session-config>

        web.xml中超时时间的单位为分钟,而setMaxInactiveInterval单位为秒。

下面通过例子来说明HttpSession的使用

首先创建一个Servlet,Session01继承自HttpServlet

        //获取Session对象

        HttpSession session=request.getSession();

        //获取Session的会话标识符

        String id=session.getId();

        System.out.println(id);

        //获取Session的创建时间

        System.out.println(session.getCreationTime());

        //获取最后一次访问时间

        System.out.println(session.getLastAccessedTime());

        //判断是否是新的session对象

        System.out.println(session.isNew());

        当获取Session对象时,会判断Session对象是否存在,存在就获取,没有就创建

IsNew()是true是新的对象,否则不是新的对象。

Session既然是为了标识一次会话,那么此次会话就应该有一个唯一的标志,这个标志就是SessionId。

        每当一次请求到达服务器,如果开启了会话(访问了Session),服务器第一步会查看是否从客户端回传一个名为JSESSIONID的cookie,如果没有则认为这是一次新的会话,会创建一个新的session对象,并用唯一定的sessionId为此次会话做一个标志。如果有JSESSIONID这个cookie回传,服务器则会根据JSESSIONID这个值去查看是否含有id为JSESSIONID的session对象,如果没有则认为是一个新的会话,重新创建一个新的session对象,并标志此次会话;如果找到了相应的session对象,则认为是之前标志过的一次会话,返回该session对象,数据达到共享。

        这里提到一个叫做JSESSIONID的cookie,这是一个比较特殊的cookie,当用户请求服务器时,如果访问了session,则服务器会创建一个名为JSESSIONID,值为获取到的session的sessionid的cookie对象,并添加到response对象中,响应给客户端,有效时间为关闭浏览器。

        所以Session的底层依赖Cookie来实现。

Session域对象

        Session用来标识一次会话,在一次会话中数据是可以共享的,这时Session作为域对象存在,可以通过setAttribute(name,value)方法向域对象中添加数据,通过getAttribute(name)从域对象中获取数据,通过removeAttribute(name)从域对象中移除数据。

        下面重新创建一个Servlet来讲解Session的域对象。

        创建一个Session02类,继承自HttpServlet。

setAttribute设置Session域对象

removeAttribute移除Session域对象

//获取Session对象

HttpSession session=request.getSession();

//设置Session域对象

session.setAttribute("uname","admin");

session.setAttribute("upwd","123456");

//移除Session对象

session.removeAttribute("upwd");

//设置request域对象

request.setAttribute("name","request_name");

//请求转发到JSP页面

request.getRequestDispatcher("index.jsp").forward(request,response);

        然后创建一个Index.jsp页面来接收这些Session域对象和Request域对象

        请求转发是一次请求,request作用域有效,session作用域有效

但是在该版本的Idea中out.print方法无法解析

点击Idea菜单中的文件→项目结构

点击项目结构后的界面展示如下图所示

选择选项卡中的“依赖”选项卡,然后点击项目结构中的“加号”

点击“加号”后的界面展示如下图所示,选择“库”

 然后选中Tomcat 8.5.99,然后点击“添加所选项”按钮

然后红色的提示就会消失。

启动该web程序

然后使用URL地址 http://localhost:8080/s001/ser02

界面结果如下图所示

        其中uname和upwd是Session域对象,但是upwd在设置后被移除了。name是Request域对象,请求转发到JSP后都可以获取到。

        然后把请求转发的代码改为重定向的代码,代码示例如下图所示

        重定向是两次请求,session还可以获取,request不能获取

再次重启该Web应用,再次访问ser02,结果如下图所

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024年618哪些数码家电值得入手?热门家电好物抢先看!

618购物狂欢节即将来临&#xff0c;这是一年一度的大促销活动&#xff0c;家电和数码产品在这个时间段内通常都会有优惠和折扣。但随着产品的多样化&#xff0c;很多时候一款产品就有多款品牌&#xff0c;在这不同品牌又各自擅长不同的东西&#xff0c;看着眼花缭乱。今天我就给…

基于python+django网易新闻+评论的舆情热点分析平台

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

Java中优雅实现泛型类型的强制转换

在Java中经常遇到将对象强制转换成泛型类的情况&#xff1a; Map<String, Object> data Map.of("name", "XiaoMing","age", 17,"scores", List.of(80, 90, 70) );List<Integer> scores (List<Integer>) data.get…

Docker容器添加修改端口映射的方法与详细步骤

1、先找到要修改的容器hash值&#xff1a; 2、然后退出docker Desktop服务 &#xff08;因为在线状态配置文件修改保存不了&#xff09; 3、资源管理器中打开最新安装的Docker的配置文件的路径&#xff1a; 4、打开后修改其中的 config.v2.json 和 hostconfig.json 5、启动…

【C++】哈希表的底层逻辑

目录 一、哈希概念 1、哈希冲突 2、哈希冲突的解决 a、闭散列 &#x1f7e2;插入 &#x1f7e2;查找 &#x1f7e2;删除 &#x1f7e2;其他类型的数据 &#x1f7e2;实现 b、 开散列 &#x1f7e2;插入 &#x1f7e2;查找 &#x1f7e2;删除 &#x1f7e2;析构 &a…

《霍格沃茨之遗》找不到emp.dll如何修复?分享5种亲测有效的方法

在我们享受电脑游戏带来的乐趣时&#xff0c;偶尔会遇到一些技术上问题&#xff0c;具体来说&#xff0c;当你启动一款游戏&#xff0c;系统却弹出一个提示“由于找不到emp.dll文件&#xff0c;因此无法继续执行代码”&#xff0c;这样的情况确实让人感到扫兴。这究竟是什么原因…

.net core ef 连表查询

Information和TypeInfo连表查询 类似&#xff1a; select st.Title1,si.* from [Star_Information] si left join Star_TypeInfo st on si.typeId2st.id 先在EfCoreDbContext.cs配置 protected override void OnModelCreating(ModelBuilder builder){base.OnModelCreating(b…

Jupyter Notebook 中使用虚拟环境的Python解释器

问题&#xff1a;创建虚拟环境&#xff0c;在pycharm中配置虚拟环境的Python解释器&#xff0c;然后在pycharm中打开ipynb&#xff0c;执行发现缺少包&#xff0c;但是虚拟环境中已经安装了 解决方式&#xff1a; 配置Jupyter Notebook 使用虚拟环境的Python解释器 1&#x…

ElasticSearch总结2

一、创建索引库&#xff1a;PUT ES中通过Restful请求操作索引库、文档。请求内容用DSL语句来表示。创建索引库和mapping的DSL语法如下&#xff1a; 整个jason 里边&#xff0c;它有一个叫mapping的属性&#xff0c;代表的是映射。映射里边有properties代表就是字段。可以看到这…

C++入门系列-缺省参数

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 缺省参数的概念 缺省参数是生命或者定义函数时为函数的参数指定一个缺省值&#xff0c;在调用该函数时&#xff0c;如果没有指定实参则采用该形参的缺省值&#xff0c;否则使用…

一单利润100+,不起眼的小生意,却能闷声发财!

今天&#xff0c;我想向大家介绍一个看似不太热门&#xff0c;但实际上需求很高的项目——酒店代订。这个项目其实很早以前就已经有人开始尝试了&#xff0c;但可能并没有被大众所熟知。简而言之&#xff0c;酒店代订就是帮助他人通过我们来预订他们想要入住的酒店。 当客户将…

ThinkPHP5 SQL注入漏洞敏感信息泄露漏洞

1 漏洞介绍 ThinkPHP是在中国使用极为广泛的PHP开发框架。在其版本5.0&#xff08;<5.1.23&#xff09;中,开启debug模式&#xff0c;传入的某参数在绑定编译指令的时候又没有安全处理&#xff0c;预编译的时候导致SQL异常报错。然而thinkphp5默认开启debug模式&#xff0c…

Allegro如何将铜皮复制到其他层

如何将铜皮复制到其他层 方法一&#xff1a; 第一步&#xff1a;选择需要复制的铜皮&#xff0c;然后按下CtrlC 第二步&#xff1a;选择要粘贴到的层面&#xff0c;然后按Ctrl V 将在所在层面创建一个新的铜皮&#xff0c;几何形状与原铜皮完全一样 方法二&#xff1a; 第一…

基于SSM的个人博客系统(二)

目录 第四章 系统设计 4.1 系统总流程 4.2 博主用例 4.3 游客用例 4.4 系统类 一、博客类 二、博客类型类 三&#xff0c;评论类&#xff1a; 四&#xff0e;友情链接类 4.5 E-R图 4.6 系统表设计 前面内容请移步 基于SSM的个人博客系统&#xff08;一&#xff09;…

docker mysql更新升级版本

一、环境说明 操作系统&#xff1a;Centos7 数据库版本&#xff1a;MySql 8.0.22 数据库中数据量不大&#xff0c;处于开发/测试环境&#xff0c;风险较低 二、升级原因 升级是因为测评漏洞&#xff0c;在进行国家三级等级保护测评过程中&#xff0c;漏扫发现多个MySql漏洞…

(十五)Servlet教程——Servlet文件上传

JSP和HTML标签一起使用&#xff0c;来允许用户把文件上传到服务器。 首先我们需要创建一个前端界面&#xff0c;创建上传文件表单时&#xff0c;需要注意以下几点&#xff1a; (1) 表单的method属性必须设置为POST方法&#xff0c; 不能使用GET方法。 (2) 表单enctype属性应该…

【Unity面试篇】Unity 面试题总结甄选 |Unity基础篇 | ❤️持续更新❤️

2.2 前言 关于Unity面试题相关的所有知识点&#xff1a;&#x1f431;‍&#x1f3cd;2023年Unity面试题大全&#xff0c;共十万字面试题总结【收藏一篇足够面试&#xff0c;持续更新】为了方便大家可以重点复习某个模块&#xff0c;所以将各方面的知识点进行了拆分并更新整理…

19 做好微服务间依赖的治理和分布式事务

在前两讲里&#xff0c;分别从微服务的对外接口、消息消费以及微服务自身的相关编码规范上阐述了“防备上游、做好自己”这两个准则如何落地。 在本讲里&#xff0c;将会讲解为什么要“怀疑下游”&#xff0c;以及有哪些手段可以落地此条准则。此外&#xff0c;还会介绍在进行…

基于SSM的个人博客系统(三)

目录 第五章 系统实现 5.1 登录模块 5.1.1 博主登录 5.2 博客管理模块&#xff1a; 5.2.1 博客查询 5.2.2 博客新建 5.2.3 博客修改 5.2.4 博客删除 5.3 博客类别管理模块 前面内容请移步 基于SSM的个人博客系统&#xff08;二&#xff09; 个人博客系统的设计…

Qt+Ubuntu20.04:打包qt

打包程序 参考 qt项目在Linux平台上面发布成可执行程序.run_qt.run不是虚拟机的配置文件-CSDN博客 Linux下Qt程序的打包发布(1)-不使用第三方工具 - 知乎 (zhihu.com) 过程 1、Release编译 先将你的程序在release下编译通过&#xff0c;保证下面打包的程序是你最新的。 2…