会话技术 #
HTTP是一种无状态协议,每当用户发出请求时,服务器就会做出响应,客户端与服务器之间的联系是离散的、非连续的,服务器无法知道连接是否来自于同一个客户端。会话技术就是为了解决这个问题,通俗来讲,为了证明你就是你
客户端会话技术:Cookie
服务器端会话技术:Session
Cookie #
- Cookie 由服务器创建,由客户端存储
- Cookie由服务端响应给客户端,在Cookie的有效生命周期中,浏览器在访问同一服务器(同一域名,不区分端口号)的所有资源的时候,会携带Cookie
- 如果cookie的名字相同的话,虽然可以写到浏览器,但是到了浏览器就值就被覆盖了
- 一个服务器可以创建多个Cookie ,所以客户端可以有多个Cookie的域名属性指向同一服务器
- 每个Cookie所存放的的数据不可以超过 4 KB
- 每个域名创建的Cookie不得超过20个
- 浏览器用户可以设定不使用Cookie
常用方法 #
// 创建Cookie对象
Cookie cookie = new Cookie("name", "tom");
// 添加Cookie
response.addCookie(cookie);
// 获取Cookie
Cookie[] cookies = request.getCookies();
// 遍历容器
for (Cookie cookie : cookies) {
System.out.println(cookie.getName() + "=" + cookie.getValue());
}
Cookie对象的生命周期 #
会话跟踪的发起端是服务器
默认情况下浏览器关闭就销毁,浏览器获得服务器响应后获得Cookie,只要不关闭就存在
设置Cookie对象生命时长 #
cookie.setMaxAge(seconds);
方法参数 #
- 负数:默认,如果为负数的话,浏览器关闭,cookie就消失了,因为cookie存储在浏览器的缓存中
- 正数:以秒为单位,不管浏览器关闭不关闭,只看时间有没有到,时间到了,就消失了,消失前cookie存储在本地磁盘
- 0:当cookie从服务器写到浏览器的时候,马上消失,也可以用来销毁已经存在的cookie
cookie的携带范围 #
1、默认情况下,访问当前项目下(同一域名)的任何资源,都会携带cookie
2、设置携带范围
cookie.setPath(String path);
//只有访问这一个资源的时候,才会携带cookie
setPath("具体的资源路径")
//只要是该服务器下所部署的项目,访问资源的时候都可以携带cookie
setPath("/")
Session #
- Session是一个域对象,代表服务器和浏览器的一次会话过程,这个过程是连续的,也可以是时断时续的,一次会话过程中,可能出现多次的请求和响应
- 每一个Session对象都有一个Session ID,可以通过
session.getId()获取 - Session 的数据是存储在服务器上面的,数据无法构造但如果能够获取某个登录用户的 Session ID 通过伪造 Session ID 的请求, 可以仿造用户身份。
- Session的实现是依赖于Cookie的
Tomcat下Session和Cookie的使用流程 #
- 客户端首次像服务器发起请求,经过服务端判断不存在key为
JSESSIONID的Cookie信息 - 服务端创建Session并且将Session ID写入Cookie,例如:
Set-Cookie:JSESSIONID=7809798C607C086C57C65C576C858787 - 客户端将Cookie保存到本地
- 客户端再次发送请求,服务端判断存在key为
JSESSIONID的Cookie,取出ID,根据ID获取Session
常用方法 #
//根据请求的Cookie获取Session对象,如果不存在则创建新的Session
HttpSession session = request.getSession();
// 根据请求的Cookie获取Session对象,如果不存在则返回null
HttpSession session = request.getSession(false);
// 向session域对象中存储数据
session.setAttribute("key", object);
// 从session域对象中获取数据
Object obj = session.getAttribute("key");
// 从session中删除数据
session.removeAttribute("key");
生命周期 #
如果浏览器关闭,服务器没有关闭 #
-
默认浏览器关闭,此Cookie消失
-
如果浏览器关闭了之后,在浏览器缓存中存储的
JSESSIONID=XXXOOO的数据,就会消失,下次再去访问服务器使,就不会携带JSESSIONID的cookie -
如果想要关闭浏览器下一次访问还携带
JSESSIONID的cookie的话,可以通过设置Cookie的生命周期来实现
Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setMaxAge(seconds);
response.addCookie(cookie);
如果浏览器不关闭,服务器关闭的话 #
-
因为浏览器没有关闭,所以JSESSIONID的cookie没有消失,一直存在
-
我们如果非正常关闭服务器,session就消失了,当我们再次开启服务器,通过浏览器访问,cookie会携带,JSESSIONID也有,但是却不配不到session的ID值,所以在服务器端重新创建一个session对象,并且重新生成一个session的id值
-
我们如果正常关闭服务器,session也会消失,但是它会进行钝化(序列化,将session中数据存储到本地磁盘),当我们再次开启服务器,session会被活化(激活,反序列化,将本地磁盘的数据还原成java中的对象),通过浏览器访问,cookie会携带,JSESSIONID也有,ID值也匹配了,数据自然就获取到了,不会创建新的session对象
Session的钝化和活化 #
- 钝化
- 当服务器正常关闭时,还存活着的Session(在设置时间内没有销毁)会随着服务器的关闭被以文件
SESSIONS.ser的形式存储在tomcat/work目录下。
- 当服务器正常关闭时,还存活着的Session(在设置时间内没有销毁)会随着服务器的关闭被以文件
- 活化
- 当服务器再次正常开启时,服务器会找到之前的
SESSIONS.ser文件,从中恢复之前保存起来的Sessio 对象,这个过程叫做Session的活化。
- 当服务器再次正常开启时,服务器会找到之前的
- 注意事项
- 想要随着Session 被钝化、活化的对象它的类必须实现
Serializable接口,还有要注意的是只有在服务器正常关闭的条件下,还未超时的Session才会被钝化成文件。当Session 超时、调用invalidate()方法或者服务器在非正常情况下关闭时,Session 都不会被钝化,因此也就不存在活化。 - 在被钝化成
SESSIONS.ser文件时,不会因为超过Session过期时间而消失,这个文件会一直存在,等到下一次服务器开启时消失。 - 当多个Session 被钝化时,这些被钝化的Session都被保存在同一个文件中,并不会为每个Session都建立一个文件。
- 想要随着Session 被钝化、活化的对象它的类必须实现
Session对象的销毁方式 #
1、关闭服务器
2、调用session.invalidate();方法
Session的生命时长 #
Session的生命时长,默认30分钟,Tomcat会开启一个后台线程每隔段时间检查Session的有效性,并删除过期的Session。
int getMaxlnactivelnterval() ,获取Session过期时间,返回值以秒为单位。
- 可以调用
session.setMaxInactiveInterval(seconds)方法进行设置,参数以秒为单位,值为零或负数,则表示会话将永远不会超时。 - 或使用
web.xml配置:参数以分钟为单位,值为零或负数,则表示会话将永远不会超时。
<session-config>
<session-timeout>minutes</session-timeout>
</session-config>