一、概述
在Web应用程序中,我们经常要跟踪用户身份。例如:当一个用户登录成功后,如果他继续访问其他页面,Web 程序如何才能识别出该用户身份?当一个用户在操作自己的购物车时,Web 程序如何才能识别出该用户身份?因为HTTP协议是一个无状态协议,即Web应用程序无法区分收到的两个HTTP请求是否是同一个浏览器发出的。为了跟踪用户状态,服务器可以向浏览器分配一个唯- -ID, 并以Cookie 的形式发送到浏览器,浏览器在后续访问时总是附带此Cookie ,这样,服务器就可以识别用户身份。
二、什么是Session?
我们把这种基于唯一ID识别用户身份的机制称为Session 。每个用户第一次访问服务器后,会自动获得一个Session ID 。如果用户在一段时间内没有访问服务器,那么Session会自动失效,下次即使带着上次分配的Session ID访问,服务器也认为这是一个新用户,会分配新的Session ID。一次Session会话中往往包含着若干次request请求。
JavaEE的Servlet 机制内建了对Session 的支持。当我们需要获取Session 时,可以通过request请求对象的getSession() 方法。例如:
HttpSession session = request.getSession();
获取HttpSession后,常见的操作方法有:
- void setAttribute(String name, 0bject value) :将指定Key -Value键值对,存入当前Session会话中。
- Object getAttribute(String name) :按照指定的Key从当前Session 会话中获取Value ,返回值为object 类型的对象,如果不存在,则返回null。
- void removeAttribute(String name) :按照指定的Key从当前Session 会话中删除Key-Value键值对。
- long getCreationTime() :获取当前Session 会话的创建时间。
- long getLastAccessedTime() :获取当前Session会话最后一次请求的访问时间。
- String getId() :获取当前Session会话的SESSION ID。
服务器识别Session 的关键就是依靠一个名为 JSESSIONID 的Cookie 。在Servlet 中第一次调用req. getSession()时,Servlet 容器自动创建一个Session ID,然后通过一个名为JSESSIONID的Cookie发送给浏览器:
使用Session 时,由于服务器把所有户的Session 都存储在内存中,如果遇到内存不足的情况,就需要把部分不活动的Session 列化到磁盘上,这会大大降低服务器的运行效率,因此,放入Session的数据不能太大,否则会影响服务器的运行。
三、什么是Cookie?
实际上,Servlet 提供的HttpSession本质上就是通过一个名为JSESSIONID 的Cookie来跟踪用户会话的。除了这个名称外,其他名称的Cookie 我们可以任意使用。
创建一个新 Cookie 时,除了指定名称和值以外,通常需要设置setPath("/") ,浏览器根据此前缀决定是否发送Cookie 。如果一个Cookie 调用了setPath("/user/") ,那么浏览器只有在请求以/user/开头的路径时才会附加此Cookie。通过setMaxAge() 设置Cookie 的有效期,单位为秒,后通过 resp. addcookie()把它添加到响应。通过创建Cookie,我们可以实现在客户端浏览器中存储数据的目的,例如保存用户名和密码。在Chrome浏览器中,单个Cookie 的长度不能超过4069个字符(包括 name,但不包括=号)。
我们可以在浏览器看到服务器发送的Cookie,以百度为例:
如果我们要读取Cookie,例如,在IndexServlet中,读取名为lang的Cookie 以获取用户设置的语言,可以写一个方法如下:
private String parseLanguageFromCookie(){
// 获取请求附带的所有Cookie
Cookie[] cookies = req.getCookies();
// 如果获取到Cookie
if(cookies != null){
//循环每个Cookie
for(Cookie cookie : cookies){
//如果Cookie名称为lang:
if(cookie.getName().equals("lang")){
// 返回Cookie的值:
return cookie.getValue();
}
}
}
// 返回默认值:
return "en";
}
所以,读取Cookie 主要依靠遍历HttpServletRequest附带的所有Cookie 。
四、Session和Cookie的区别
保存位置:
- Cookie 通过客户端浏览器,以文件形式保存在本地机器,数据容量受浏览器限制,一般不超过3kb;Session以对象形式保存在服务器端内存。
数据内容:
- Cookie中不允许出现特殊内容(中文、特殊符号); Session中允许保存任意内容;
存储周期:
- Cokie的存储周期由Nax Age属性设置,可以长期保存;Session的实现依靠一个名叫DSESSIONID 的cookie,Max Age过期时间默认为-1,关闭浏览器窗口,该Cookie则失效,对应的Session从而也失效;