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
自动超时销毁.