Cookie 与 Session

Servlet 的技术现在看来比较老旧,但是学好它的底层原理对于日后的框架学习非常有益。于是最近整理了一下其中 Cookie 与 Session 的相关知识,打好基础。

这两个东西的用处在哪里呢?想象在一个网上商城购物,你先在页面 A 挑选了几件商品,然后准备付款,跳入了新的页面 B ,这上面就有你刚刚所选的商品等信息。由于 HTTP 是无状态的,也就是说,你对于页面 A 的请求和页面 B 的之间没有关系,那这期间所产生的状态信息——也就是上面的选购商品——就必须保存下来。Cookie 与 Session 就来完成这个任务。

Cookie 是由服务器发送给客户端(浏览器)的大小有限的数据,以键值对的方式保存在客户端中。

工作原理

  1. 浏览器向客户端发送请求;
  2. 服务器根据情况生成 Cookie 对象,将数据保存在该对象内;
  3. 把这个 Cookie 对象 放在 response 对象中,发回给客户端;
  4. 客户端接收到响应,在本地将 Cookie 保存;
  5. 再次请求服务器时,浏览器将其放进 request 中发送出去;
  6. 服务器取得 Cookie 信息。

实际应用

首先是 Cookie 的创建:

1
2
Cookie cookie = new Cookie("name", "value");
response.addCookie(cookie);

实际 Cookie 对象除了名称和值的属性外,还有域名、路径和有效期等,可以通过 setDomain()setPath()setMaxAge() 等方法去设置。
假如想要销毁 Cookie 对象,就直接 setMaxAge(0) ,让其有效期为 0 即可。
然后是取出 Cookie 的内容:

1
Cookie[] cookies = request.getCookies();
  1. Cookie 可以保存一些用户登录时的账密码等,方便用户,好像是给用户尝了尝“甜头”,这也是其名字的由来。
  2. Cookie 对象保存的数据必须是 String 类型的,其数量与大小都受到了限制;甚至用户也可以在浏览器里直接设置不使用 Cookie 功能。
  3. Cookie 由于将数据保存在本地,很容易被篡改,造成安全问题。

Session

Session 在服务端保存状态数据,这一点区别于 Cookie。

工作原理

  1. 浏览器发出请求到服务器。
  2. 服务器首先检查这个客户端的请求里是否已包含了一个 Session 标识,即 Session ID:
    (a) 如果有,那就根据 ID 将这个 Session 检索出来使用(检索不到会新建一个);
    (b) 如果没有,则服务端生成一个 Session 和对应的 Session ID。
  3. 接下来,服务器发回一个响应,将这个 ID 发给客户端保存,客户端一般使用 Cookie 保存。不过,客户端是可以禁用 Cookie 的,那么还可以用 URL 重写技术,在 URL 后面直接加上 ID 参数,当客户端再次发出请求时,服务器也可以取得 Session ID。
  4. 浏览器再次发出请求就会发送该 Session ID。
  5. 服务器得到这个 ID,找到对应的 Session 对象,取得数据。

实际应用

创建:

1
2
HttpSession session = request.getSession();
HttpSession session = request.getSession(true);

对于第二条,如果 Session 不存在,则创建一个;假如写入 false 则在不存在 Session 时返回 null
还有一些常用方法:

1
2
3
4
String getId();      // 得到对象编号
Object getAttribute(String name); // 返回对应名称的对象
void setMaxInactiveInterval(int interval); //设置有效时长(单位为秒)
void invalidate(); // 手动销毁

关于 Session

Session 什么时候会被删除?

  1. Session超时,即在设定的时间内服务器未收到对应客户端的请求;
  2. 程序调用HttpSession.invalidate();
  3. 服务器关闭或服务停止。

另外,Session 会在一定时间内保存在服务器上。当访问增多,会比较占用服务器的性能。若要减轻服务器负担,应当使用 Cookie。