Cookie 意爲「小甜點」,是由 W3C 組織提出,最先由 Netscape 社區發展的一種機制。目前 Cookie 已經成爲標準,全部的主流瀏覽器如 IE、Netscape、Firefox、Opera 等都支持 Cookie。其實Cookie就是一個鍵和一個值構成的,隨着服務器端的響應發送給客戶端瀏覽器。而後客戶端瀏覽器會把Cookie保存起來,當下一次再訪問服務器時把Cookie再發送給服務器。html
注意,不一樣瀏覽器之間是不共享Cookie的。也就是說在你使用IE訪問服務器時,服務器會把Cookie發給IE,而後由IE保存起來,當你在使用FireFox訪問服務器時,不可能把IE保存的Cookie發送給服務器。java
Cookie是經過HTTP請求和響應頭在客戶端和服務器端傳遞的:
Cookie:請求頭,客戶端發送給服務器端;web
Set-Cookie:響應頭,服務器端發送給客戶端;windows
若是服務器端發送重複的Cookie那麼會覆蓋原有的Cookie,例如客戶端的第一個請求服務器端發送的Cookie是:Set-Cookie: a=A;第二請求服務器端發送的是:Set-Cookie: a=AA,那麼客戶端只留下一個Cookie,即:a=AA。瀏覽器
咱們設定客戶端訪問AServlet,AServlet在響應中添加Cookie,瀏覽器會自動保存Cookie。而後客戶端訪問BServlet,這時瀏覽器會自動在請求中帶上Cookie,BServlet獲取請求中的Cookie並將其打印出來。服務器
package cn.itcast.servlet; import java.io.IOException; import java.util.UUID; 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 XINGGou * */ public class AServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); String id = UUID.randomUUID().toString();//生成一個隨機字符串 Cookie cookie = new Cookie("id", id);//建立Cookie對象,指定名字和值 response.addCookie(cookie);//在響應中添加Cookie對象 response.getWriter().print("已經給你發送了ID"); } }
package cn.itcast.servlet; 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 XINGGou * */ public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); Cookie[] cs = request.getCookies();//獲取請求中的Cookie if(cs != null) {//若是請求中存在Cookie for(Cookie c : cs) {//遍歷全部Cookie if(c.getName().equals("id")) {//獲取Cookie名字,若是Cookie名字是id response.getWriter().print("您的ID是:" + c.getValue());//打印Cookie值 } } } } }
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); Cookie cookie = new Cookie("lasttime", new Date().toString()); cookie.setMaxAge(60 * 60); response.addCookie(cookie); Cookie[] cs = request.getCookies(); String s = "歡迎首次訪問!!!"; if(cs != null) { for(Cookie c : cs) { if(c.getName().equals("lasttime")) { s = "親!您上一次訪問本站的時間是:" + c.getValue(); } } } response.getWriter().print(s); }
如今有WEB應用A,向客戶端發送了10個Cookie,這就說明客戶端不管訪問應用A的哪一個Servlet都會把這10個Cookie包含在請求中!可是也許只有AServlet須要讀取請求中的Cookie,而其餘Servlet根本就不會獲取請求中的Cookie。這說明客戶端瀏覽器有時發送這些Cookie是多餘的!
能夠經過設置Cookie的path來指定瀏覽器,在訪問什麼樣的路徑時,包含什麼樣的Cookie。cookie
瀏覽器在訪問BServlet時,是否要帶上AServlet保存的Cookie呢?這要看Cookie的path了。
現有資源以下:app
// 沒有設置Cookie的path AServlet { Cookie c = new Cookie("xxx", "XXX"); response.addCookie(c); } // 設置了Cookie的path爲/xg CServlet { Cookie c = new Cookie("yyy", "YYY"); c.setPath="/xg"; response.addCookie(c); } DServlet { Cookie c = new Cookie("zzz", "ZZZ"); resposne.addCookie(c); }
在BServlet中保存的Cookie沒有設置path,那麼它的path默認爲當前BServlet的所在路徑,即「/xg/servlet」。
在CServlet中保存的Cookie設置了path爲/xg。
在DServlet中保存的Cookie沒有設置path,那麼它的path默認爲DServlet的所在路徑,即「/xg/servlet/user」dom
當訪問AServlet時,是否要帶上xxx這個Cookie呢?由於AServlet的訪問路徑爲/xg/servlet/BServlet,它包含了xxx的path,即/xg/servlet,因此須要帶上。
當訪問AServlet時,是否要帶上yyy這個Cookie呢?由於AServlet的訪問路徑爲/xg/servlet/BServlet,它包含了xxx的path,即/xg,因此須要帶上。
當訪問AServlet時,是否要帶上zzz這個Cookie呢?由於AServlet的訪問路徑爲/xg/servlet/BServlet,它不包含zzz的path,即/xg/servlet/user,因此不會帶上。webapp
==Cookie的domain屬性可讓網站中二級域共享Cookie,次要!==
百度你是瞭解的對吧!
http://www.baidu.com
http://zhidao.baidu.com
http://news.baidu.com
http://tieba.baidu.com
如今我但願在這些主機之間共享Cookie(例如在www.baidu.com中響應的cookie,能夠在news.baidu.com請求中包含)。很明顯,如今不是路徑的問題了,而是主機的問題,即域名的問題。處理這一問題其實很簡單,只須要下面兩步:
當domain爲「.baidu.com」時,不管前綴是什麼,都會共享Cookie的。可是如今咱們須要設置兩個虛擬主機:www.baidu.com和news.baidu.com。
找到C:\WINDOWS\system32\drivers\etc\hosts文件,添加以下內容
127.0.0.1 localhost 127.0.0.1 www.baidu.com 127.0.0.1 news.baidu.com
找到server.xml文件,添加<Host>元素,內容以下:
<Host name="www.baidu.com" appBase="F:\webapps\www" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"/> <Host name="news.baidu.com" appBase="F:\webapps\news" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"/>
Cookie c = new Cookie("id", "baidu"); c.setPath("/"); c.setDomain(".baidu.com"); c.setMaxAge(60*60); response.addCookie(c); response.getWriter().print("OK");
把A項目的WebRoot目錄複製到F:\webapps\www目錄下,並把WebRoot目錄的名字修改成ROOT。
Cookie[] cs = request.getCookies(); if(cs != null) { for(Cookie c : cs) { String s = c.getName() + ": " + c.getValue() + "<br/>"; response.getWriter().print(s); } }
把B項目的WebRoot目錄複製到F:\webapps\news目錄下,並把WebRoot目錄的名字修改成ROOT。
success!!!
Cookie的name和value都不能使用中文,若是但願在Cookie中使用中文,那麼須要先對中文進行URL編碼,而後把編碼後的字符串放到Cookie中。
向客戶端響應中添加Cookie
String name = URLEncoder.encode("姓名", "UTF-8"); String value = URLEncoder.encode("張三", "UTF-8"); Cookie c = new Cookie(name, value); c.setMaxAge(3600); response.addCookie(c);
從客戶端請求中獲取Cookie
response.setContentType("text/html;charset=utf-8"); Cookie[] cs = request.getCookies(); if(cs != null) { for(Cookie c : cs) { String name = URLDecoder.decode(c.getName(), "UTF-8"); String value = URLDecoder.decode(c.getValue(), "UTF-8"); String s = name + ": " + value + "<br/>"; response.getWriter().print(s); } }
<body> <h1>商品列表</h1> <a href="/day06_3/GoodServlet?name=ThinkPad">ThinkPad</a><br/> <a href="/day06_3/GoodServlet?name=Lenovo">Lenovo</a><br/> <a href="/day06_3/GoodServlet?name=Apple">Apple</a><br/> <a href="/day06_3/GoodServlet?name=HP">HP</a><br/> <a href="/day06_3/GoodServlet?name=SONY">SONY</a><br/> <a href="/day06_3/GoodServlet?name=ACER">ACER</a><br/> <a href="/day06_3/GoodServlet?name=DELL">DELL</a><br/> <hr/> 您瀏覽過的商品: <% Cookie[] cs = request.getCookies(); if(cs != null) { for(Cookie c : cs) { if(c.getName().equals("goods")) { out.print(c.getValue()); } } } %> </body>
public class GoodServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String goodName = request.getParameter("name"); String goods = CookieUtils.getCookValue(request, "goods"); if(goods != null) { String[] arr = goods.split(", "); Set<String> goodSet = new LinkedHashSet(Arrays.asList(arr)); goodSet.add(goodName); goods = goodSet.toString(); goods = goods.substring(1, goods.length() - 1); } else { goods = goodName; } Cookie cookie = new Cookie("goods", goods); cookie.setMaxAge(1 * 60 * 60 * 24); response.addCookie(cookie); response.sendRedirect("/Xing/index.jsp"); } }
public class CookieUtils { public static String getCookValue(HttpServletRequest request, String name) { Cookie[] cs = request.getCookies(); if(cs == null) { return null; } for(Cookie c : cs) { if(c.getName().equals(name)) { return c.getValue(); } } return null; } }
不知兄臺到此是否能有一種重溫之感,亦或感慨萬分呢?哈哈哈!!!