一、Cookie是什么?

  Cookie翻译成中文是小甜点,小饼干的意思。在HTTP中它表示服务器发送给客户端浏览器的小甜点。其实Cookie就是一个键和值构成的,随着服务器端的响应发送给客户端浏览器,然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器的时候会把Cookie再发送给服务器

二、Cookie规范

  你大可以放心,Cookie不会占满你的磁盘。因为一个Cookie最多只有4kb,一个服务器最多只能发送客户端20个Cookie,并且浏览器最多可以保存300个Cookie。当然,在浏览器大战的今天,一些浏览器为了打败对手,可能会对Cookie规范“扩展”了一些,例如每个Cookie的大小为8KB,最多可保存500个Cookie等!但也不会出现把你磁盘占满的可能!

  不同的浏览器之间不能共享Cookie!!!

三、Cookie的作用

  Cookie的作用可大了,但无论怎么夸大Cookie的作用都离不开“跟踪客户端状态”这句话。我们知道Cookie是服务器保存在客户端的信息,然后客户端会在下次你请求把Cookie在还给服务器,这样服务器就可以通过信息来识别客户端了。

  就好比你去医院看病,第一次去要买病例,然后你去任何科室都需要你出示卡片。只要你出示卡片,医生就会知道你去过哪些科室,看了哪些病!卡片上只有一个ID,它就是Cookie,而你本人就是客户端,而医生就是服务器了。

四、Cookie的属性

  Cookie最重要的4个属性:名字(name)、值(value)、路径(path)和域(domain)。

  我们现在只需要关心name和value,而path和domain可以先不去了解!但后面也会去讲解它的作用。

  javax.servlet.http.Cookie类只有一个构造器:Cookie(String name,String value)。你应该知道怎么创建一个Cookie对象:Cookie c = new Cookie("id","1");

五、保存Cookie到客户端

  保存Cookie到客户端,这是响应工作的一部分,所有这个方法时response对象的。并且Cookie是HTTP协议的内容,所以保存Cookie是HttpServletResponse类的方法。

public void addCookie(Cookie c) 添加Cookie对象到当前到response对象

  上面的方法可以被调用多次,从而完成添加多个Cookie对象到response中。

package cn.cookie;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 添加Cookie到客户端 */@SuppressWarnings("serial")public class CookieDemo1 extends HttpServlet {	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		Cookie c = new Cookie("id", "1");		response.addCookie(c);	}	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		this.doGet(request, response);	}}

  使用浏览器访问

  当再次访问的时候,查看请求头信息是否存在Cookie这个头信息。

六、Cookie的生命周期

  Cookie会在客户端存活多久呢?这就是Cookie的生命了。默认情况下,Cookie只在浏览器的内存中存活,也就是说,当你关闭浏览器后,Cookie就会消失(也称为会话级Cookie)。

  可以使用cookie.setMaxAge(int expiry)来设置Cookie的存活时间。参数expiry表示Cookie存活的秒数。

public void setMaxAge(60*60)

  表示你Cookie对象可存活1小时。就算关闭浏览器,就算重启客户端电脑,Cookie也会存活1小时。因为当MaxAge大于0的时候,浏览器不仅会把cookie保存在浏览器内存中,还会把cookie的硬盘中。

public void setMaxAge(-1)

  cookie的MaxAge属性的默认值就是-1:表示只在浏览器的内存中存活。一旦关闭浏览器窗口,那么cookie就会消失。

public void setMaxAge(0)

  cookie被作废!表示cookie不在内存中存活,也不在硬盘上存活,这样的cookie的设置的目的就只有一个,那就是覆盖客户端原来的这个cookie,使其作废。

七、服务端读取Cookie

  我们现在已经可以保存Cookie到客户端了,但是我们还不知道怎么让服务器获取Cookie。

  如果浏览器保存了Cookie,那么会在下一次请求时候会把Cookie放到请求头中发送给服务器中,  这是服务器只需要在请求中读取Cookie,既然是在请求中读取Cookie,那么当然是使用request对象读取了。

public Cookie[] getCookies()

  【注意】上面的方法返回的是Cookie数组,而不是一个Cookie对象。如果请求中没有Cookie,那么该方法返回null。

package cn.cookie;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 服务器端获取Cookie * @author Administrator * */@SuppressWarnings("serial")public class CookieDemo extends HttpServlet {	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		response.setContentType("text/html;charset=utf-8");		//获取当前请求中的所有Cookie对象		Cookie[]  cookies = request.getCookies();		//如果返回的数组不为null		if(cookies != null){			//循环遍历,得到每一个Cookie对象			for (Cookie cookie : cookies) {				//获取Cookie的名称				String name = cookie.getName();				//获取Cookie的值				String value = cookie.getValue();				response.getWriter().print(name+","+value);			}		}	}	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		this.doGet(request, response);	}}

八、Cookie的路径

  Cookie路径会影响请求中是否包含Cookie。

  Cookie还有一个path属性,可以通过Cookie的setPath(String path)方法来设置。

  也就是说,就算你不设置Cookie的path路径,Cookie也是有路径的,这个路径就是请求的路径。例如在请求

  例如请求的路径是

  到现在为止我们还没说过Cookie的path有什么用,现在我们来聊聊path的作用。首先声明一点,path不是指Cookie在客户端存放的路径!!!不同的浏览器存放Cookie的路径是不同的!!你不能通过Cookie的path来指定Cookie文件的存放路径!!!

  那么,Cookie的path是干什么的呢?假设当前的浏览器已经有两个Cookie:

c1:name=id;value=haha;path=/day09/c2:name=name;value=hehe;path=/day09/serlvet/

  当访问

  当访问

  

  也就是说,在访问子路径的时候,会包含其父路径的Cookie,而在访问父路径的时候,不包含子路径的Cookie。

    如果你想在BServlet中设置的Cookie,在客户端访问AServlet的时候也包含在请求头中,那么就需要设置BServlet中的path。

c2.setPath("/day09/");硬编码
c2.setPath(request.getContextPath()+"/");软编码

  这样就可以设置Cookie的路径,保存在访问AServlet的时候,也会包含BServlet中添加的Cookie。

九、Cookie中的域名(不重要)

十、Cookie中保存中文

  Cookie中是不可以设置中文的,但可以使用URLEncoder.encode()方法编码后再保存到Cookie中。在获取Cookie的时候,需要先使用URLDecoder.decode()方法解码,再使用。

package cn.cookie;import java.io.IOException;import java.net.URLDecoder;import java.net.URLEncoder;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@SuppressWarnings("serial")public class CookieDemo3 extends HttpServlet {	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		//向客户端添加Cookie		String name = URLEncoder.encode("姓名","utf-8");  		String value = URLEncoder.encode("张三","utf-8");		Cookie c = new Cookie(name, value);		c.setMaxAge(60 * 60);		response.addCookie(c);				//从客户端请求中获取Cookie		response.setContentType("text/html;charset=utf-8");		Cookie[] cookies = request.getCookies();		if(cookies != null){			for (Cookie cookie : cookies) {				String cookieName = URLDecoder.decode(cookie.getName(), "utf-8");				String cookieValue = URLDecoder.decode(cookie.getValue(), "utf-8");				response.getWriter().println(cookieName+","+cookieValue);			}		}	}	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		this.doGet(request, response);	}}

总结:

  Cookie是客户端技术,程序把每个用户的数据以Cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源的时候,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。

  

案例:记录上次访问时间

package cn.cookie;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@SuppressWarnings("serial")public class ReadLastTime extends HttpServlet {	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		//设置响应的编码		response.setContentType("text/html;charset=utf-8");		//从客户端获取所有的Cookie		Cookie[] cookies = request.getCookies();		//如果cookies == null,表示第一次登陆啊,		if(cookies == null){			response.getWriter().println("亲,欢饮访问本系统");		}else{//不是第一次登陆			for (Cookie cookie : cookies) {				if(cookie.getName().equals("last")){//如果cookie的key是last,就说明是本系统的设置的cookie					response.getWriter().print("你上次访问的时间是"+cookie.getValue());				}			}		}		//回写cookie到客户端		response.addCookie(new Cookie("last", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));	}	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		this.doGet(request, response);	}}

案例:访问商品的浏览信息

productList.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>      
<%=basePath%>">        
My JSP 'productList.jsp' starting page    
    
.img1{ width: 160px; height:140px; }               
手电筒    
电话    
电视
    
冰箱    
手表    
电脑        

    

浏览记录

    

清除记录

<% Cookie[] cookies = request.getCookies(); if(cookies != null){ for(Cookie cookie :cookies){ String[] ids = cookie.getValue().split(","); for(String id : ids){%>
<%=id%>.jpg"/><% } } } %>      

Product.java

package cn.cookie;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** *浏览商品记录  */@SuppressWarnings("serial")public class Product extends HttpServlet {	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		/**		 *1.获取请求参数		 *2.获取Cookie数组,通过指定的名称,查找Cookie,		 *3.如果Cookie是 空,是第一次访问,		 *	创建Cookie,回写到浏览器		 *4.如果Cookie不是null,不是第一次访问		 *	说明了Cookie中存在了id		 *	判断当前的id,是否已经存在Cookie的value中?		 *		如果存在,不用操作		 *		如果不存在,在后面追加product=1,2		 *5.重定向商品列表页面		 */		//获取请求参数 目的是:存放到Cookie中		String id = request.getParameter("id");		//获取所有的Cookie,查找指定名称的Cookie		Cookie[] cookies = request.getCookies();		//查找指定名称的cookie		Cookie cookie = getCookieByName(cookies,"product");		//如果Cookie=null,说明是第一次访问		if(cookie == null){			Cookie c = new Cookie("product", id);			c.setMaxAge(60 * 60 * 24 *7);			response.addCookie(c);		}else{			//如果Cookie中不存在Id			//获取Cookie的value(value=1,2,3)			String value = cookie.getValue();			//判断,当前商品的id是否在cookie中			String[]  values = value.split(",");			//判断ID是否在value[]数组中			if(!checkId(values,id)){				cookie.setValue(value+","+id);				cookie.setMaxAge(60 * 60 * 24 *7);				response.addCookie(cookie);			}		}				//重定向到商品展示页面		response.sendRedirect("/day11/cookie/productList.jsp");	}	/**	 * 判断,当前的id是否包含在value数组中	 * @param values	 * @param value	 * @return	 */	private boolean checkId(String[] values, String value) {		for (String string : values) {			if(value.equals(string)){				return true;			}		}		return false;	}	/**	 * 根据指定的名称查找Cookie	 * @param cookies	 * @param string	 * @return	 */	private Cookie getCookieByName(Cookie[] cookies, String string) {		//表示第一次访问		if(cookies == null){			return null;		}else{			//遍历Cookie[],拿到指定名称的Cookie			for (Cookie cookie : cookies) {				if(cookie.getName().equals(string)){					return  cookie;				}			}		}		return null;	}	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		this.doGet(request, response);	}}

ClearProduct.java

package cn.cookie;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@SuppressWarnings("serial")public class ClearProduct extends HttpServlet {	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		Cookie c = new Cookie("product", "");		c.setMaxAge(0);		response.addCookie(c);		response.sendRedirect("/day11/cookie/productList.jsp");	}	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		this.doGet(request, response);	}}