Cookie and Session

1. 会话的概念

1.1 基本介绍

用户开一个浏览器,点击多个超链接,访问服务器多个 web 资源,然后关闭浏览器,整个过程称之为一个会话。

1.2 实际意义

  • 每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,服务器要想办法为每个用户保存这些数据,这就是接下来要介绍的 Cookie 与 Session 技术;

2. 会话相关技术

2.1.1 基本介绍

Cookie (小甜饼) 是客户端技术,服务器把每个用户的数据以 cookie 的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的 web 资源时,就会带着各自的数据去。这样, web 资源处理的就是用户各自的数据了。
但是 Cookie 只是存储在浏览器本地的,他与这个会话并没有一一对应的关系,这其实就是与 Session 的主要区别。
注意事项:

  1. Cookie 是服务器在客户端保存用户的信息,比如登录名,浏览历史等, 就可以以 cookie 方式保存.
  2. Cookie 信息就像是小甜饼 (cookie 中文) 一样,数据量并不大,服务器端在需要的时候可以从客户端/浏览器读取 (http 协议),可以通过图来理解;

解读:

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

解读:

  1. 当生命周期设置为 0 时,Cookie 的失效时间被设置为默认时间 1970 年;

2.1.4.1 基本介绍

  1. Cookie 有效路径 Path 的设置;
  2. Cookie 的 path 属性可以有效的过滤哪些 Cookie 可以发送给服务器,哪些不发。 path 属性是通过请求的地址来进行有效的过滤;

2.1.4.2 基本规则

cookie1.setPath = /工程路径 
cookie2.setPath = /工程路径/aaa 

请求地址url: http://ip:端口/工程路径/资源 
cookie1 会发给服务器 
cookie2 不会发给服务器 

请求地址url: http://ip:端口/工程路径/aaa/资源 
cookie1 会发给服务器 
cookie2 会发给服务

解读:

  1. 如果 Path 为请求 url 子集的时候,就可以发送给服务器;
  2. 不管请求资源是否存在,只要满足上一规则,就会发送这个 Cookie;

2.1.5 应用实例

  1. 保存用户名密码,在一定时间内实现自动登录;
  2. 保存上次登录时间;
  3. 网页的个性化定制;
  4. ...

Cookie 本质就是一对 k-v。

2.1.6.1 创建

Cookie cookie = new Cookie(String name, String val); 
cookie.setMaxAge();//保存时间 

2.1.6.2 添加到浏览器(客户端)

response.addCookie(cookie);
Cookie[] cookies = request.getCookies();
cookie.getName();
cookie.getValue();

2.1.7 注意事项

  1. 一个 Cookie 只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值 (VALUE),就相当于一条数据,而不是键值对集合;
  2. 一个 WEB 站点可以给一个浏览器发送多个 Cookie,一个浏览器也可以存储多个 WEB 站点提供的 Cookie;
  3. cookie 的总数量没有限制,但是每个域名的 COOKIE 数量和每个 COOKIE 的大小是有限制的 (不同的浏览器限制不同, 知道即可) , Cookie 不适合存放数据量大的信息;
  4. 注意,删除 cookie 时,path 必须一致,否则不会删;

如果存放中文的 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 基本原理

  1. 当用户打开浏览器,访问某个网站, 操作 session 时,服务器就会在内存 (在服务端) 为该浏览器分配一个 session 对象,该 session 对象被这个浏览器独占, 如图;

    那么如何分辨一个用户对应的是哪个 Session 呢?利用 JsessionId 这个 Cookie 对象。

  2. 这个 session 对象也可看做是一个容器/集合, session 对象默认存在时间为 30min (这是在 tomcat/conf/web. xml),也可修改;

2.2.3 Session 底层原理

解读,浏览器是如何找到对应的 session 的:

  1. 初始阶段浏览器先发出 http 请求,若有 JsessionId 则会带入,之后被服务端接受;
  2. 服务端解析请求,判断请求是否带有 JsessionID。
    • 若有就判断是否在服务端本地存有相应的 session 对象。若存在对象就直接执行相关业务;若没有就创建一个 session,并且重新分配一个 JsessionID 用于覆盖原来“无效的 JsessionID。
    • 若没有就在内存创建一个 session 对象,并分配一个 JsessionID 与该会话一一对应;
  3. 在执行完相关业务后,服务端判断是否在内存中创建了新的 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 就会被销毁:
    1. 值为正数的时候,设定 Session 的超时时长;
    2. 负数表示永不超时;
  • 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();
  • 本质区别就是 Cookie 是与会话弱相关的,Session 是与会话强相关的,Session 与会话一一对应,而 Cookie 就没有这种对应关系;
  • 生命周期的差距,见生命周期即可;
  • 存储结构的差距:Cookie 是一对 k-v,而 Session 是一组 k-v 组成的类似于 HashMap 的结构;
posted @ 2023-06-13 19:01  yelanyanyu  阅读(12)  评论(0)    收藏  举报