Cookie和Session
本篇文章简单记录了关于Web会话管理技术的学习笔记。
目前常用的会话管理技术是Cookie与Session
- Cookie通过在客户端记录信息确定用户身份
- Session通过在服务器端记录信息确定用户身份。
会话管理
- 会话管理: 管理浏览器和服务器之间的会话过程中产生的会话数据
Cookie
Cookie机制的引入
在Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。
Cookie就是记录会话数据这样的一种机制。它可以弥补HTTP协议无状态的不足。
Cookie原理
Cookie是客户端技术,服务器把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去,这样,web资源处理的就是用户各自的数据了。
Cookie机制的流程
- 服务器创建cookie对象,把会话数据存储到cookie对象中。
new Cookie("name","value"); - 服务器发送cookie信息到浏览器
response.addCookie(cookie);
举例: set-cookie: name=xiseven (隐藏发送了一个set-cookie名称的响应头) - 浏览器得到服务器发送的cookie,然后保存在浏览器端。
- 浏览器在下次访问服务器时,会带着cookie信息
举例: cookie: name=xiseven (隐藏带着一个叫cookie名称的请求头) - 服务器接收到浏览器带来的cookie信息
request.getCookies();
Cookie核心API
1)构造Cookie对象
Cookie(java.lang.String name, java.lang.String value)
2)设置cookie
//设置cookie的有效访问路径
void setPath(java.lang.String uri)
//设置cookie的有效时间
void setMaxAge(int expiry)
//设置cookie的值
void setValue(java.lang.String newValue)
//设置cookie的有效域
void setDomain(String pattern)
3)发送cookie到浏览器端保存
//发送cookie
void response.addCookie(Cookie cookie)
4)服务器接收cookie
//接收cookie
Cookie[] request.getCookies()
Cookie细节
-
一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
-
void setPath(java.lang.String uri) :设置cookie的有效访问路径。有效路径指的是cookie的有效路径保存在哪里,那么浏览器在有效路径下访问服务器时就会带着cookie信息,否则不带cookie信息。
-
void setMaxAge(int expiry) : 设置cookie的有效时间。
正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。
负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了!!
零:表示删除同名的cookie数据
注意,删除cookie时,path必须一致,否则不会删除 -
一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
-
Cookie中存储中文
//必须使用URLEncoder类里面的encode(String s, String enc)方法进行中文转码
Cookie cookie = new Cookie("userName", URLEncoder.encode("用户名", "UTF-8"));
response.addCookie(cookie);
//获取cookie中的中文数据,使用URLDecoder类里面的decode(String s, String enc)进行解码
URLDecoder.decode(cookies[i].getValue(), "UTF-8");
Session
Session机制的引入
- Cookie的局限:
- Cookie只能存字符串类型。不能保存对象
- 不能直接存储中文字符。
- 1个Cookie的容量不超过4KB。
因为Cookie的种种局限所以引入Session机制,可以很好的解决以上的问题
Session原理
Session是服务器技术,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。
Session机制的流程:
以下是服务器内部的行为
- 第一次访问创建session对象,给session对象分配一个唯一的ID,叫JSESSIONID
new HttpSession(); - 把JSESSIONID作为Cookie的值发送给浏览器保存
Cookie cookie = new Cookie("JSESSIONID", sessionID);
response.addCookie(cookie); - 第二次访问的时候,浏览器带着JSESSIONID的cookie访问服务器
- 服务器得到JSESSIONID,在服务器的内存中搜索是否存放对应编号的session对象。
服务器搜索session对象的伪代码
if(找到){
return map.get(sessionID);
}
存储session对象的Map结构
Map<String,HttpSession>
<"001", s1>
<"001", s2>
- 如果找到对应编号的session对象,直接返回该对象
- 如果找不到对应编号的session对象,创建新的session对象,继续走1的流程
Session核心API
方法 | 描述 |
---|---|
void setAttribute(String attribute, Object value) | 设置Session属性。value参数可以为任何Java Object。通常为Java Bean。value信息不宜过大 |
String getAttribute(String attribute) | 返回Session属性 |
Enumeration getAttributeNames() | 返回Session中存在的属性名 |
void removeAttribute(String attribute) | 移除Session属性 |
String getId() | 返回Session的ID。该ID由服务器自动创建,不会重复 |
long getCreationTime() | 返回Session的创建日期。返回类型为long,常被转化为Date类型,例如:Date createTime = new Date(session.getCreationTime()) |
long getLastAccessedTime() | 返回Session的最后活跃时间。返回类型为long |
int getMaxInactiveInterval() | 返回Session的超时时间。单位为秒。超过该时间没有访问,服务器认为该Session失效 |
void setMaxInactiveInterval(int second) | 设置Session的超时时间。单位为秒 |
boolean isNew() | 返回该Session是否是新创建的 |
void invalidate() | 使该Session失效 |
Session细节
-
两个getSession方法:
- getSession(true) / getSession() : 创建或得到session对象。没有匹配的session编号,自动创建新的session对象。
- getSession(false) : 得到session对象。没有匹配的session编号,返回null
-
Session对象销毁时间:
- 手动销毁Session对象invalidate()
- 默认情况30分钟不访问服务器自动回收
- 手动修改Session回事时间setMaxInactiveInterval()
- 全局修改Session有效时间(修改web.xml)
<!-- 修改session全局有效时间:分钟 --> <session-config> <session-timeout>1</session-timeout> </session-config>
-
浏览器禁用Cookie后的Session处理
解决方案:URL重写,使用一下方法可将SessionId信息写入URL,不必依赖于Cookie- response. encodeRedirectURL(java.lang.String url)
用于对sendRedirect方法后的url地址进行重写。 - response. encodeURL(java.lang.String url)
用于对表单action和超链接的url地址进行重写
- response. encodeRedirectURL(java.lang.String url)