1、Cookie是什麼?css
Cookie翻譯成中文是小甜點,小餅乾的意思。在HTTP中它表示服務器發送給客戶端瀏覽器的小甜點。其實Cookie就是一個鍵和值構成的,隨着服務器端的響應發送給客戶端瀏覽器,而後客戶端瀏覽器會把Cookie保存起來,當下一次再訪問服務器的時候會把Cookie再發送給服務器html
2、Cookie規範java
你大能夠放心,Cookie不會佔滿你的磁盤。由於一個Cookie最多隻有4kb,一個服務器最多隻能發送客戶端20個Cookie,而且瀏覽器最多能夠保存300個Cookie。固然,在瀏覽器大戰的今天,一些瀏覽器爲了戰勝對手,可能會對Cookie規範「擴展」了一些,例如每一個Cookie的大小爲8KB,最多可保存500個Cookie等!但也不會出現把你磁盤佔滿的可能!web
不一樣的瀏覽器之間不能共享Cookie!!!數組
3、Cookie的做用瀏覽器
Cookie的做用可大了,但不管怎麼誇大Cookie的做用都離不開「跟蹤客戶端狀態」這句話。咱們知道Cookie是服務器保存在客戶端的信息,而後客戶端會在下次你請求把Cookie在還給服務器,這樣服務器就能夠經過信息來識別客戶端了。服務器
就比如你去醫院看病,第一次去要買病例,而後你去任何科室都須要你出示卡片。只要你出示卡片,醫生就會知道你去過哪些科室,看了哪些病!卡片上只有一個ID,它就是Cookie,而你本人就是客戶端,而醫生就是服務器了。cookie
4、Cookie的屬性
dom
Cookie最重要的4個屬性:名字(name)、值(value)、路徑(path)和域(domain)。jsp
咱們如今只須要關心name和value,而path和domain能夠先不去了解!但後面也會去講解它的做用。
javax.servlet.http.Cookie類只有一個構造器:Cookie(String name,String value)。你應該知道怎麼建立一個Cookie對象:Cookie c = new Cookie("id","1");
5、保存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); } }
使用瀏覽器訪問http://localhost:8080/day09/demo1,而後能夠查看響應頭信息中是否有set-Cookie這個頭信息。
當再次訪問的時候,查看請求頭信息是否存在Cookie這個頭信息。
6、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,使其做廢。
7、服務端讀取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); } }
8、Cookie的路徑
Cookie路徑會影響請求中是否包含Cookie。
Cookie還有一個path屬性,能夠經過Cookie的setPath(String path)方法來設置。
也就是說,就算你不設置Cookie的path路徑,Cookie也是有路徑的,這個路徑就是請求的路徑。例如在請求http://localhost:8080/day09/demo1時,服務器響應了一個Cookie,那麼這個Cookie的默認路徑就是/day09/。
例如請求的路徑是http://localhost:8080/day09/servlet/demo1,服務器響應了一個Cookie,那麼這個Cookie的默認路徑就是/day09/servlet/。
到如今爲止咱們還沒說過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/
當訪問http://localhost:8080/day09/*的時候,請求頭中會包含c1,而不會包含c2。
當訪問http://localhost:8080/day09/servlet/*的時候,請求頭中會包含c1和c2。
也就是說,在訪問子路徑的時候,會包含其父路徑的Cookie,而在訪問父路徑的時候,不包含子路徑的Cookie。
若是你想在BServlet中設置的Cookie,在客戶端訪問AServlet的時候也包含在請求頭中,那麼就須要設置BServlet中的path。
c2.setPath("/day09/");硬編碼
c2.setPath(request.getContextPath()+"/");軟編碼
這樣就能夠設置Cookie的路徑,保存在訪問AServlet的時候,也會包含BServlet中添加的Cookie。
9、Cookie中的域名(不重要)
10、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+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'productList.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <style type="text/css"> .img1{ width: 160px; height:140px; } </style> </head> <body> <img class="img1" src="/day11/img/1.jpg"/><a href="/day11/product?id=1">手電筒</a> <img class="img1" src="/day11/img/2.jpg"/><a href="/day11/product?id=2">電話</a> <img class="img1" src="/day11/img/3.jpg"/><a href="/day11/product?id=3">電視</a><br/> <img class="img1" src="/day11/img/4.jpg"/><a href="/day11/product?id=4">冰箱</a> <img class="img1" src="/day11/img/5.jpg"/><a href="/day11/product?id=5">手錶</a> <img class="img1" src="/day11/img/6.jpg"/><a href="/day11/product?id=6">電腦</a> <hr/> <h3>瀏覽記錄</h3> <h3><a href="/day11/clearProduct">清除記錄</a></h3> <% Cookie[] cookies = request.getCookies(); if(cookies != null){ for(Cookie cookie :cookies){ String[] ids = cookie.getValue().split(","); for(String id : ids){ %> <img class="img1" src="/day11/img/<%=id%>.jpg"/> <% } } } %> </body> </html>
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); } }