Cookie and Session
1. 会话的概念
1.1 基本介绍
用户开一个浏览器,点击多个超链接,访问服务器多个 web 资源,然后关闭浏览器,整个过程称之为一个会话。
1.2 实际意义
- 每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,服务器要想办法为每个用户保存这些数据,这就是接下来要介绍的 Cookie 与 Session 技术;
2. 会话相关技术
2.1 Cookie
2.1.1 基本介绍
Cookie (小甜饼) 是客户端技术,服务器把每个用户的数据以 cookie 的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的 web 资源时,就会带着各自的数据去。这样, web 资源处理的就是用户各自的数据了。
但是 Cookie 只是存储在浏览器本地的,他与这个会话并没有一一对应的关系,这其实就是与 Session 的主要区别。
注意事项:
- Cookie 是服务器在客户端保存用户的信息,比如登录名,浏览历史等, 就可以以 cookie 方式保存.
- Cookie 信息就像是小甜饼 (cookie 中文) 一样,数据量并不大,服务器端在需要的时候可以从客户端/浏览器读取 (http 协议),可以通过图来理解;
2.1.2 Cookie 原理解析

解读:
- 服务端接收到浏览器发来的请求;
- 服务端执行相关的业务,假设这里创建了几个 Cookie(注意这里的 Cookie 还未打入浏览器,只存在于服务端),并放在了响应体中;
- 之后服务端将响应打回浏览器;
- 浏览器解析响应,并在本地创建 Cookie;
2.1.3 Cookie 生命周期
- Cookie 的生命周期指的是如何管理 Cookie 什么时候被销毁(删除) ;
- setMaxAge (秒数) :
- 正数,表示在指定的秒数后过期;
- 负数,表示浏览器关闭,Cookie 就会被删除(默认值是-1)。即代表这个 Cookie 是会话级的;
- 0,表示马上删除 Cookie,浏览器会直接进行删除,即不在本地存储了;
原理: 创建 Cookie 时,请求中会自带失效的时间,当浏览器再次请求的时候,发现时间超过了规定的生命周期,就下次请求就不会带上 Cookie,并进行本地的删除。见下图:

解读:
- 当生命周期设置为 0 时,Cookie 的失效时间被设置为默认时间 1970 年;
2.1.4 Cookie 有效路径
2.1.4.1 基本介绍
- Cookie 有效路径 Path 的设置;
- Cookie 的 path 属性可以有效的过滤哪些 Cookie 可以发送给服务器,哪些不发。 path 属性是通过请求的地址来进行有效的过滤;
2.1.4.2 基本规则
cookie1.setPath = /工程路径
cookie2.setPath = /工程路径/aaa
请求地址url: http://ip:端口/工程路径/资源
cookie1 会发给服务器
cookie2 不会发给服务器
请求地址url: http://ip:端口/工程路径/aaa/资源
cookie1 会发给服务器
cookie2 会发给服务
解读:
- 如果 Path 为请求 url 子集的时候,就可以发送给服务器;
- 不管请求资源是否存在,只要满足上一规则,就会发送这个 Cookie;
2.1.5 应用实例
- 保存用户名密码,在一定时间内实现自动登录;
- 保存上次登录时间;
- 网页的个性化定制;
- ...
2.1.6 Cookie 基本使用
Cookie 本质就是一对 k-v。
2.1.6.1 创建
Cookie cookie = new Cookie(String name, String val);
cookie.setMaxAge();//保存时间
2.1.6.2 添加到浏览器(客户端)
response.addCookie(cookie);
2.1.6.3 读取请求中的 Cookie
Cookie[] cookies = request.getCookies();
cookie.getName();
cookie.getValue();
2.1.7 注意事项
- 一个 Cookie 只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值 (VALUE),就相当于一条数据,而不是键值对集合;
- 一个 WEB 站点可以给一个浏览器发送多个 Cookie,一个浏览器也可以存储多个 WEB 站点提供的 Cookie;
- cookie 的总数量没有限制,但是每个域名的 COOKIE 数量和每个 COOKIE 的大小是有限制的 (不同的浏览器限制不同, 知道即可) , Cookie 不适合存放数据量大的信息;
- 注意,删除 cookie 时,path 必须一致,否则不会删;
2.1.8 Cookie 中文乱码解决方案
如果存放中文的 cookie, 默认报错, 可以通过 URL 编码和解码(利用 URLDecoder 和 URLEncoder 类)来解决,不建议存放中文的 cookie 信息。
实例:
2.1.8.1 中文编码
//以utf-8的编码方式保存“我爱你”
String urlName = URLEncoder.encode("我爱你", "utf-8");
Cookie nameCookie = new Cookie("Love", urlName); //添加 cookie[Love-我爱你] response.addCookie(nameCookie);
Cookie cookie2 = new Cookie("key1", "key1_value");
response.addCookie(cookie2);
2.1.8.2 中文解码
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
Cookie[] cookies = request.getCookies(); //处理的中文乱码问题
for (Cookie cookie : cookies) {
//以utf-8的方式解码
writer.println("Cookie[" + cookie.getName() + "=" +
URLDecoder.decode(cookie.getValue(),"utf-8") + "]
");
}
2.2 Session
2.2.1 基本介绍
- Session 是服务器端技术,服务器在运行时为每一个用户的浏览器创建一个其独享的 session 对象/集合;
- 由于 session 为各个用户浏览器独享,所以用户在访问服务器的不同页面时,可以从各自的 session 中读取/添加数据, 从而完成相应任务;
- session 的存储结构是一个类似于 HashMap 的逻辑结构,存储的是一组 k-v;
2.2.2 Session 基本原理
-
当用户打开浏览器,访问某个网站, 操作 session 时,服务器就会在内存 (在服务端) 为该浏览器分配一个 session 对象,该 session 对象被这个浏览器独占, 如图;

那么如何分辨一个用户对应的是哪个 Session 呢?利用 JsessionId 这个 Cookie 对象。
-
这个 session 对象也可看做是一个容器/集合, session 对象默认存在时间为 30min (这是在 tomcat/conf/web. xml),也可修改;
2.2.3 Session 底层原理

解读,浏览器是如何找到对应的 session 的:
- 初始阶段浏览器先发出 http 请求,若有 JsessionId 则会带入,之后被服务端接受;
- 服务端解析请求,判断请求是否带有 JsessionID。
- 若有就判断是否在服务端本地存有相应的 session 对象。若存在对象就直接执行相关业务;若没有就创建一个 session,并且重新分配一个 JsessionID 用于覆盖原来“无效的 JsessionID。
- 若没有就在内存创建一个 session 对象,并分配一个 JsessionID 与该会话一一对应;
- 在执行完相关业务后,服务端判断是否在内存中创建了新的 session,若有则返回新的 JsessionID(Cookie 对象);

解读:
- 以上所有的原理的伊始就是
request.getSession(),所有的逻辑从这里开始; - 特别注意: 在服务器重新启动时,会清空所有的 cookie 和 session,故若浏览器带有 JsessionID 再次向服务端发送请求的时候,服务器会发现没有该对象,会重新创建 session 对象,并分配一个 JsessionID ,返回响应时浏览器覆盖原有的 JsessionID;
2.2.4 Session 的生命周期
2.2.4.1 基本介绍
-
Session 的生命周期指的是 :
客户端/浏览器两次请求最大间隔时长,而不是累积时长;而 Cookie 则是以累积时长计算的。即当客户端访问了自己的 session,session 的生命周期将从 0 开始重新计算。(解读: 指的是同一个会话两次请求之间的间隔时间) ;

-
底层: Tomcat 用一个线程来轮询会话状态,如果某个会话的空闲时间超过设定的最大值,则将该会话销毁;
-
浏览器关闭了,session 就会销毁吗?不一定。
2.2.4.2 相关API
- public void setMaxInactiveInterval (int interval) 设置 Session 的超时时间(以秒为单位),超过指定的时长,Session 就会被销毁:
- 值为正数的时候,设定 Session 的超时时长;
- 负数表示永不超时;
- public int getMaxInactiveInterval () 获取 Session 的超时时间;
- public void invalidate () 让当前 Session 会话立即无效;
- 如果没有调用 setMaxInactiveInterval () 来指定 Session 的生命时长,Tomcat 会以 Session 默认时长为准,Session 默认的超时为 30 分钟,可以在 tomcat 的 web. xml 设置;
2.2.5 基本使用
2.2.5.1 创建及获取 session
HttpSession hs = request.getSession();
2.2.5.2 添加属性
hs.setAttribute(String name, Object val);
2.2.5.3 得到某个属性
Object obj=hs.getAttribute(String name);
2.2.5.4 删除某个属性
hs.removeAttribute(String name)
2.2.5.5 判断 session 是不是刚创建的
hs.isNew();
2.3 Cookie 与 Session 的区别
- 本质区别就是 Cookie 是与会话弱相关的,Session 是与会话强相关的,Session 与会话一一对应,而 Cookie 就没有这种对应关系;
- 生命周期的差距,见生命周期即可;
- 存储结构的差距:Cookie 是一对 k-v,而 Session 是一组 k-v 组成的类似于 HashMap 的结构;

浙公网安备 33010602011771号