session机制
- 什么是会话?
- session机制
- 为什么需要session对象来保存会话状态呢?
- 只要B和S断开了,那么关闭浏览器这个动作,服务器知道吗?
- 为什么不使用request(ServletRequest)对象保存会话状态?为什么不使用application(ServletContext)对象保存会话状态?
- 思考:session对象的实现原理
- ❤️如何获取session?
- session超时机制
- ❤️session的实现原理
- 为什么关闭浏览器,会话结束?
- Cookie禁用了,session还能找到吗?
- Cookie禁用了,session机制还能实现吗?
- 总结
什么是会话?
会话对应的英文单词:session;
-
用户打开浏览器,进行一系列操作,然后最终将浏览器关闭,这整个过程叫做:一次会话,会话在服务器有一个对应的
Java对象,这个Java对象就叫做:session。
什么是一次请求:
用户在浏览器上点击了一下,然后到页面停下来,可以粗略认为是一次请求,请求对应的服务器也有个Java对象是:request -
在一次会话中可以进行多次请求;
在Java的servlet规范当中,session对应的类名:HttpSession(jakarta.servlet.http.HttpSession)
session机制
session机制属于B/S结构的一部分,如果使用php语言开发WEB项目,同样也是有session这种机制的,session机制实际上是一种规范,然后不同的语言对这种会话机制都有实现。
session对象最主要的作用:保留会话状态。(用户登录成功了,这是一种登录成功的状态,使用session来保存会话状态)
为什么需要session对象来保存会话状态呢?
- 因为
Http协议是一种无状态协议,Session不能依据HTTP连接来判断是否为同一个用户。- 无状态:请求的时候,B和S是连接的,但是请求结束之后,连接断了,为什么要这么做?Http协议为什么要设计成这样?减少服务器的压力,请求的瞬间是连接的,请求结束之后连接断开,这样服务器压力小。
只要B和S断开了,那么关闭浏览器这个动作,服务器知道吗?
- 不知道,服务器是不知道浏览器关闭的。
为什么不使用request(ServletRequest)对象保存会话状态?为什么不使用application(ServletContext)对象保存会话状态?
request.setAttribute()存,request.getAttribute()取,ServletContext也有这个方法,request是请求域,ServletContext是应用域。
ServletContex对象域太大
request请求域(HttpServletRequest)、session会话域(HttpSession)、application应用域(ServletContext)
request<session<application一个用户一个会话,如果使用应用域的话,用户之间会混在一起了。(可以自身进行测试,用两个浏览器模拟两个用户,发送请求给服务器时,此时容器里面都是公用同一个应用域的,这样会导致两用户混在一起,不好管理。)
思考:session对象的实现原理
HttpSession session = request.getSession();- 这行代码很神奇,获取session对象,张三访问的时候获取的
session对象就是张三的,李四访问的时候获取的session对象就是李四的,不同用户之间所得到的session对象都不是一致的。它实现了用户之间的不相干性,同时也维持着一次会话。
❤️如何获取session?
HttpSession session = request.getSession();从服务器中获取当前的session对象, 如果没有获取到任何session对象,则新建;HttpSession session = request.getSession(false);从服务器中获取session对象 如果获取不到session,则不会新建,返回一个null。
session超时机制
session对象销毁情况有两种:
-
一种是超时销毁
浏览器关闭的时候,由于Http是一种无状态协议,所以服务器是不知道浏览器关闭的,所以session的销毁要依靠session超时机制。

-
一种是手动销毁
系统提供了“安全退出”,用户可以点击这个按钮,这样服务器知道你退出了,服务器会自动销毁session对象。这里的实现是在后端代码中调用了session对象的invalidate()方法,使得session对象被销毁。

❤️session的实现原理
在Web服务器中有一个session列表,类似于map集合,这个map集合的key存储的是session ID;
这个map集合的value存储的是对应的session对象,用户发送第一次请求的时候,服务器会创建一个新的session对象,同时给session对象生成一个ID,然后Web服务器会将session的ID发送给浏览器,浏览器将session的ID保存在浏览器的缓存中(浏览器的运行内存中)。
用户发送第二次请求的时候,会自动将浏览器中的sessionID自动发送给服务器,服务器获取到sessionID,然后从session列表中查找到对应的session对象。
为什么关闭浏览器,会话结束?
因为sessionID是在浏览器的运行内存中的,浏览器关闭之后,浏览器中保存的sessionID就消失了,下次重新打开浏览器之后,浏览器缓存中没有这个sessionID,发送请求的时候,请求报文中没有对应的sessionID,服务器自然找不到对应的session对象。session对象找不到等同于会话结束,此时服务器会使用超时机制销毁对象。
Cookie禁用了,session还能找到吗?
cookie禁用是什么意思?服务器正常发送cookie给浏览器,但是浏览器不要了,拒收了。并不是服务器不发了。
- 找不到
session对象了,每一次请求都会产生新的session对象。
以下是如何禁用所有cookie:

Cookie禁用了,session机制还能实现吗?
- 可以,需要使用
URL重写机制!设置URL的参数。URL重写机制提高开发者的成本,开发人员在编写任何请求路径的时候,后面都要添加一个sessionID,给开发带来了很大的难度,很大的成本,所以大部分的网站都是这样设计的:你要是禁用cookie,你就别用了!
如何设置URL参数呢?
URL路径段有三个组件=》参数(param ;)组件、查询(query ?)组件、片段(frag #)组件。
参数组件负责解析URL的应用程序需要这些协议参数来访问资源,以分号(;)与资源定位路径分割。
首先复制以下sessionID:

然后配置参数:

可以通过地址发现是同一个session对象!!!
总结
- 其实
sessionID就是Cookie,是由服务器自动发送的名为JESSIONID的Cookie,不需要程序员手动去创建; session之所以可以实现识别不同用户的功能,就是因为sessionID(Cookie);- 这个
sessionID对应的Cookie的maxAge就是默认为-1的,也就是说这个Cookie不是在硬盘中而是在运行内存中的,关闭浏览器后浏览器就没了; - 为什么会引入
Session会话机制,就是因为Http是一种无状态协议; Session的生命周期:Session的生命周期是不固定的,创建时是不固定的,当首次访问JSP文件时,(没有修改page指令的session属性值)那么当容器把jsp翻译成Servlet时会创建Session对象的,那么后面该用户所用的就是这个Session对象了,销毁Session一个是手动调invalidate方法,一个是Session自动超时销毁.



















