1.什么是Cookie
Http 协议一共有五大特点:1.支持客户/服务器模式; 2.简单快速; 3.灵活; 4.无连接; 5.无状态。
Http无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。早期这么做的原因是 HTTP 协议产生于互联网,因此服务器需要处理同时面向全世界数十万、上百万客户端的网页访问,但每个客户端(即浏览器)与服务器之间交换数据的间歇性较大(即传输具有突发性、瞬时性),并且网页浏览的联想性、发散性导致两次传送的数据关联性很低,大部分通道实际上会很空闲、无端占用资源。因此 HTTP 的设计者有意利用这种特点将协议设计为请求时建连接、请求完释放连接,以尽快将资源释放出来服务其他客户端。
Http无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送 HTTP 请求之后,服务器根据请求,会给我们发送数据过来,但是,发送完,不会记录任何信息。HTTP 是一个无状态协议,这意味着每个请求都是独立的。HTTP 协议这种特性有优点也有缺点,优点在于解放了服务器,每一次请求“点到为止”不会造成不必要连接占用,缺点在于每次请求会传输大量重复的内容信息。
客户端与服务器进行动态交互的 Web 应用程序出现之后,HTTP 无状态的特性严重阻碍了这些应用程序的实现,毕竟交互是需要承前启后的,简单的购物车程序也要知道用户到底在之前选择了什么商品。于是,用于保持 HTTP 连接状态的技术就应运而生了,一种是Cookie,一种是Session。
Http的无状态性要求出现一种保存c/s间状态的机制,Cookie是保存到客户端的一个文本文件,与特定客户相关,以“名-值”对的形式保存数据。Cookie最典型的应用是判定注册用户是否已经登录网站,用户可能会得到提示,是否在下一次进入此网站时保留用户信息以便简化登录手续,这些都是 Cookie 的功用。另一个重要应用场合是“购物车”之类处理。用户可能会在一段时间内在同一家网站的不同页面中选择不同的商品,这些信息都会写入 Cookie,以便在最后付款时提取信息。
2.java提供的操作Cookie的API
实例化Cookie对象,传入Cookie名称和Cookie值;
取得Cookie的名字;
取得Cookie值;
设置Cookie值;
设置Cookie的最大保存时间,即Cookie的有效期,如果没有使用该方法,那么Cookie的有效期只在一次会话过程中有效,关闭浏览器Cookie失效。当设置Cookie的有效期时,比如设置为30分钟,那么关闭浏览器后,Cookie会保存在本地硬盘上,在30分钟内,打开浏览器访问服务器时,浏览器都会把Cookie一起带上,这样就可以在服务器端获取到客户端浏览器传过来的Cookie里面的信息了。
获得Cookie的有效期;
设置cookie的有效路径,比如把cookie的有效路径设置为"/xdp",那么浏览器访问"xdp"目录下的web资源时,都会带上cookie,再比如把cookie的有效路径设置为"/xdp/gacl",那么浏览器只有在访问"xdp"目录下的"gacl"这个目录里面的web资源时才会带上cookie一起访问,而当访问"xdp"目录下的web资源时,浏览器是不带Cookie的。
获得cookie的有效路径;
设置cookie的有效域;
获得cookie的有效域;
3.Cookie使用范例
使用cookie记录用户上一次访问的时间
示例代码如下:
package test; import java.io.IOException; import java.io.PrintWriter; import java.text.DateFormat; 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; public class CookieTest extends HttpServlet { @SuppressWarnings("deprecation") public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置服务器端以UTF-8编码进行输出 response.setCharacterEncoding("UTF-8"); //设置浏览器以UTF-8编码进行接收,解决中文乱码问题 response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); //获取浏览器访问访问服务器时传递过来的cookie数组 Cookie[] cookies = request.getCookies(); //如果用户是第一次访问,那么得到的cookies将是null if (cookies!=null) { out.write("您上次访问的时间是:"); for (int i = 0; i < cookies.length; i++) { Cookie cookie = cookies[i]; if (cookie.getName().equals("lastAccessTime")) { Long lastAccessTime =Long.parseLong(cookie.getValue()); DateFormat df=new SimpleDateFormat(); Date date = new Date(lastAccessTime); out.write(df.format(date)); } } }else { out.write("这是您第一次访问本站!"); } //用户访问过之后重新设置用户的访问时间,存储到cookie中,然后发送到客户端浏览器 Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");//创建一个cookie,cookie的名字是lastAccessTime //cookie.setMaxAge(24*60*60); //将cookie对象添加到response对象中,这样服务器在输出response对象中的内容时就会把cookie也输出到客户端浏览器 response.addCookie(cookie); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
首次访问时,会得到如下的结果:
刷新之后,
在上面的例子中,在程序代码中并没有使用setMaxAge方法设置cookie的有效期,所以当关闭浏览器之后,cookie就失效了,要想在关闭了浏览器之后,cookie依然有效,那么在创建cookie时,就要为cookie设置一个有效期。如下所示:
Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+""); cookie.setMaxAge(24*60*60); response.addCookie(cookie);
用户第一次访问时,服务器发送给浏览器的cookie就存储到了硬盘上,这样即使关闭了浏览器,下次再访问时,也依然可以通过cookie获取用户上一次访问的时间。
4.Cookie的注意事项
1.一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。比如上面的示例代码中,
Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+""); 该Cookie标识的是浏览器的访问时间,名称为lastAccessTime,值为当前获得的具体访问时间。
2.一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。结合上一条,一个Cookie只能标识一种信息,而一个WEB站点可以给一个WEB浏览器发送多个Cookie,那么浏览器获得的信息就不是单一的。
3.浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
4.如果创建了一个Cookie,并将他发送到浏览器(response.addCookie(cookie)),默认情况下它是一个会话级别的Cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该Cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该Cookie。
5.设置Cookie时,映射路径中,同一个servlet/jsp设置的Cookies能够被同一个路径或子路径下面的servlet/jsp读到。
5.删除Cookie
将Cookie的有效期设置为0,则会命令浏览器删除该Cookie。
package test;
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;
public class CookieTest2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//创建一个名字为lastAccessTime的cookie
Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");
//将cookie的有效期设置为0,命令浏览器立即删除该cookie
cookie.setMaxAge(0);
//项目所有目录均有效,很关键,否则不敢保证删除
cookie.setPath("/");
//重新写入,将覆盖之前的
response.addCookie(cookie);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
6.Cookie存取中文
要想在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")