这里讲session和cookie放在一起写, 不是说他们之间有什么关系,仅最近一个项目中同时用到。偷懒,放一起整理下
Session:
Session的发明是为了填补HTTP协议的局限。请注意HTTP协议是通过用户发出请求,服务器作出响应的方式来工作的,这种用户端和服务器端的联系就是离散的,非连续的。HTTP协议不能提供允许服务器跟踪用户请求的功能。在服务器端完成响应用户的请求之后,服务器不能继续与该浏览器继续保持连接。从服务器这端来看,每一个请求都是独立的,因此HTTP协议被认为是无状态协议,当用户在多个主页间切换时,服务器无法知道他的身份。 Session的出现就是为了弥补这个局限。利用Session,您就可以当一个用户在多个主页间切换的时候也能保存他的信息。这样很多以前根本无法去做的事情就变得简单多了。
用户从到达某个特定的主页到离开为止的那段时间,每个用户都会单独获得一个Session。
Java Servlet定义了一个HttpSession接口,实现的Session的功能,在Servlet中使用Session的过程
(1) 使用HttpServletRequest的getSession方法得到当前存在的session,如果当前没有定义session,则创建一个新的session,还可以使用方法getSession()
(2) 写session变量。可以使用方法HttpSession.setAttribute(name,value)来向Session中存储一个信息。也可以使用HttpSession.putValue(name,value),但这个方法已经过时了。
(3)读Session变量。可以使用方法HttpSession.getAttribute(name)来读取Session中的一个变量值,如果name是一个没有定义的变量,那么返回的是null。需要注意的是,从getAttribute读出的变量类型是Object,必须使用强制类型转换,比如:
String uid = (String) session.getAttribute("uid");
也可以使用HttpSession.getValue(name),但是这个方法也已经过时了。
(4) 关闭session,当时用完session后,可以使用session.invalidate()方法关闭session。但是这并不是严格要求的。因为,Servlet引擎在一段时间之后,自动关闭seesion。
常用的session操作如下:
//向session中添加数据
request.getSession().setAttribute("warehouseout", list);
//获取session中的数据
List eInbill=(List) request.getSession().getAttribute("warehousein");
//删除session中的数据
request.getSession().removeAttribute("warehouseout")
Cookie:
/**
* 添加新的Cookie
* @param name
* @param valueHttpServletResponse
*/
public static void setNewCookie(String name,String value,HttpServletResponse response) {
try {
Cookie cookie=new Cookie(name,value);
cookie.setMaxAge(60*60*24);//设置24小时生存期,当设置为负值时,则为浏览器进程Cookie(内存中保存),关闭浏览器就失效。 response.addCookie(cookie);
} catch (RuntimeException e) {
// TODO: handle exception
}
}
/**
* 获取Cookie值
* @param name
* @param request
* @return
*/
public static String getCookieValue(String name,HttpServletRequest request) {
String value="";
try {
Cookie[] cookies=request.getCookies();
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equalsIgnoreCase(name)) {
value=cookies[i].getValue();
}
}
} catch (RuntimeException e) {
// TODO: handle exception
}
return value;
}
/**
* 删除cookie中对应数值
* @param name
* @param request
* @param response
*/
public static void deleteCookies(String name,HttpServletRequest request,HttpServletResponse response) {
try {
Cookie[] cookies=request.getCookies();
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equalsIgnoreCase(name)) {
cookies[i].setValue(null);
cookies[i].setMaxAge(0);//设置为0为立即删除该Cookie
response.addCookie(cookies[i]);
}
}
} catch (RuntimeException e) {
// TODO: handle exception
}
}
/**
* 增加规定cookie中的数值
* @param name
* @param value
* @param request
* @param response
*/
public static void addnewCookieValue(String name,BigDecimal value,HttpServletRequest request,HttpServletResponse response) {
try {
Cookie[] cookies=request.getCookies();
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equalsIgnoreCase(name)) {
cookies[i].setValue(new BigDecimal(cookies[i].getValue().trim()).add(value).toString());
response.addCookie(cookies[i]);
}
}
} catch (RuntimeException e) {
// TODO: handle exception
}
}
/**
* 减去规定cookie中的数值
* @param name
* @param value
* @param request
* @param response
*/
public static void subCookieValue(String name,BigDecimal value, HttpServletRequest request,HttpServletResponse response) {
try {
Cookie[] cookies=request.getCookies();
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equalsIgnoreCase(name)) {
cookies[i].setValue(new BigDecimal(cookies[i].getValue()).subtract(value).toString());
response.addCookie(cookies[i]);
}
}
} catch (RuntimeException e) {
// TODO: handle exception
}
}
cookie的其他操作:
cookie.setPath("/test/test2"); 设置Cookie路径,不设置的话为当前路径(对于Servlet来说为request.getContextPath() + web.xml里配置的该 Servlet的url-pattern路径部分)
删除设置路径的cookie时,应制定删除位置,不设置该路径,默认为删除当前路径Cookie
假设路径结构如下
test/test2/test345/test555/test666
a.相同键名的Cookie(值可以相同或不同)可以存在于不同的路径下。
b. 删除时,如果当前路径下没有键为"key"的Cookie,则查询全部父路径,检索到就执行删除操作(每次只能删除一个与自己最近的父路径Cookie)
必须指定与设定cookie时使用的相同路径来删除更改cookie,而且cookie的键名不论大写、小写或大小混合都要指定路径。
键名小写时,如果当前路径为/test/test2,如果找不到再向上查询/test、/test555、/test345,如果还找不到就查询/ 。(/test555/test666不查询)
键名大小写混合或大写时,不指定路径则默认删除当前路径,并且不向上查询。
c 读取Cookie时只能读取直接父路径的Cookie。
如果当前路径为/test/test2,要读取的键为"key"。当前路径读取后,还要读取/test,/test读取后,还要读取/
d.在做Java的web项目时,由于一般的Web服务器(如Tomcat或Jetty)都用Context来管理不同的Web Application,这样对于每个
Context有不同的Path,
在一个Server中有多个Web Application时要特别小心,不要设置Path为/的Cookie,容易误操作。(当然前提是域名相同)