Cookie 与 Session

Servlet 的技术现在看来比较老旧,但是学好它的底层原理对于日后的框架学习非常有益。于是最近整理了一下其中 Cookie 与 Session 的相关知识,打好基础。
这两个东西的用处在哪里呢?想象在一个网上商城购物,你先在页面 A 挑选了几件商品,然后准备付款,跳入了新的页面 B ,这上面就有你刚刚所选的商品等信息。由于 HTTP 是无状态的,也就是说,你对于页面 A 的请求和页面 B 的之间没有关系,那这期间所产生的状态信息——也就是上面的选购商品——就必须保存下来。Cookie 与 Session 就来完成这个任务。
Cookie
Cookie 是由服务器发送给客户端(浏览器)的大小有限的数据,以键值对的方式保存在客户端中。
工作原理
- 浏览器向客户端发送请求;
- 服务器根据情况生成 Cookie 对象,将数据保存在该对象内;
- 把这个 Cookie 对象 放在 response 对象中,发回给客户端;
- 客户端接收到响应,在本地将 Cookie 保存;
- 再次请求服务器时,浏览器将其放进 request 中发送出去;
- 服务器取得 Cookie 信息。
实际应用
首先是 Cookie 的创建:
1 | Cookie cookie = new Cookie("name", "value"); |
实际 Cookie 对象除了名称和值的属性外,还有域名、路径和有效期等,可以通过 setDomain()
、setPath()
和 setMaxAge()
等方法去设置。
假如想要销毁 Cookie 对象,就直接 setMaxAge(0)
,让其有效期为 0 即可。
然后是取出 Cookie 的内容:
1 | Cookie[] cookies = request.getCookies(); |
关于 Cookie
- Cookie 可以保存一些用户登录时的账密码等,方便用户,好像是给用户尝了尝“甜头”,这也是其名字的由来。
- Cookie 对象保存的数据必须是 String 类型的,其数量与大小都受到了限制;甚至用户也可以在浏览器里直接设置不使用 Cookie 功能。
- Cookie 由于将数据保存在本地,很容易被篡改,造成安全问题。
Session
Session 在服务端保存状态数据,这一点区别于 Cookie。
工作原理
- 浏览器发出请求到服务器。
- 服务器首先检查这个客户端的请求里是否已包含了一个 Session 标识,即 Session ID:
(a) 如果有,那就根据 ID 将这个 Session 检索出来使用(检索不到会新建一个);
(b) 如果没有,则服务端生成一个 Session 和对应的 Session ID。 - 接下来,服务器发回一个响应,将这个 ID 发给客户端保存,客户端一般使用 Cookie 保存。不过,客户端是可以禁用 Cookie 的,那么还可以用 URL 重写技术,在 URL 后面直接加上 ID 参数,当客户端再次发出请求时,服务器也可以取得 Session ID。
- 浏览器再次发出请求就会发送该 Session ID。
- 服务器得到这个 ID,找到对应的 Session 对象,取得数据。
实际应用
创建:
1 | HttpSession session = request.getSession(); |
对于第二条,如果 Session 不存在,则创建一个;假如写入 false
则在不存在 Session 时返回 null
。
还有一些常用方法:
1 | String getId(); // 得到对象编号 |
关于 Session
Session 什么时候会被删除?
- Session超时,即在设定的时间内服务器未收到对应客户端的请求;
- 程序调用HttpSession.invalidate();
- 服务器关闭或服务停止。
另外,Session 会在一定时间内保存在服务器上。当访问增多,会比较占用服务器的性能。若要减轻服务器负担,应当使用 Cookie。