Cookie
根据早期的 HTTP 协议,每次 request-reponse 时,都要重新建立 TCP 连接。TCP 连接每次都重新建立,所以服务器无法知道上次请求和本次请求是否来自于同一个客户端。因此,HTTP通信是无状态的。服务器认为每次请求都是一个全新的请求,无论该请求是否来自同一地址。
于是出现了 Cookie,它把少量的用户信息存储在用户自己电脑上,因为它在浏览器中同一个域名下是全局的,用户访问时浏览器会自动把 Cookie 发送到服务器,服务端就可以从该域名下任意页面读取 Cookie 中的信息,以判断登陆状态。
Session
但 Cookie 存在用户端,存储尺寸也有大小限制,用户自身还可以禁用,甚至可见并修改,安全性极差。为了安全,又能方便地读取全局信息,于是出现了新的存储会话机制,Session(信息存放在服务器端,也很好地解决了安全问题)
多数容器是采用 Cookie 机制来实现 Session 机制,也就是说,利用 Cookie 来保存 “客户端” 和 “服务器里会话对象” 之间的对应关系。
机制实现
当容器创建一个新的 HttpSession 对象后,会生成一个随机数,称之为会话ID,并将ID值封装成一个名为 JSESSIONID 的 Cookie,返回给客户端;
之后的请求,在调用 request.getSession() 获得会话对象时,容器会先从 Http 请求中获取 JSESSIONID 的值,根据值查找到对应的会话对象,返回使用;
如果没有获得JSESSIONID值,则容器认为当前请求没有相关联的会话对象,会重复第一步进行生成。
HttpSession
一个常见的错误是以为 Session 在有客户端访问时就被创建(若第一次访问某Web应用的一个JSP页面,且该页面的page指定的Session属性为false,此时就不会产生Session对象)。
某服务端程序(如Servlet)调用HttpServletRequest.getSession(true) 或者 HttpServletRequest.getSession()这样的语句时才会被创建。
若第一次访问某Web应用的一个JSP页面,且该页面的Session属性为true,则服务器会自动为该页面分配一个HttpSession对象。
注意
清空浏览器缓存只会使存储在客户端浏览器内存中的 JSESSIONID
失效,不会使服务器端的 Session 对象失效。