Cookie的工作原理和應(yīng)用詳解
1. Cookie 原理
1.1 Cookie 背景信息
客戶端狀態(tài)管理技術(shù),將狀態(tài)信息保存在客戶端。網(wǎng)景公司發(fā)明,瀏覽器會話技術(shù)。一個Cookie只能標(biāo)識一種信息,它至少含有一個標(biāo)識該信息的名稱name
和設(shè)置值value
。瀏覽器一般只允許存放300
個Cookie,每個站點(diǎn)最多存放20
個Cookie,每個大小限制為4kb
。
1.2 Cookie 工作原理
執(zhí)行流程:
1.瀏覽器向服務(wù)器發(fā)送請求,服務(wù)器需要創(chuàng)建cookie,服務(wù)器會通過響應(yīng)攜帶cookie,在產(chǎn)生響應(yīng)時會產(chǎn)生Set-Cookie響應(yīng)頭,從而將cookie信息傳遞給了瀏覽器;
2.當(dāng)瀏覽器再次向服務(wù)器發(fā)送請求時,會產(chǎn)生cookie請求頭,將之前服務(wù)器的cookie信息再次發(fā)送給了服務(wù)器,然后服務(wù)器根據(jù)cookie信息跟蹤客戶端狀態(tài)。
1.3 Cookie 創(chuàng)建、獲取、修改
chrome谷歌瀏覽器查看cookie信息,瀏覽器地址欄輸入:
- chrome://settings/content/cookies
- chrome://settings/siteData
Cookie 創(chuàng)建:
// 用響應(yīng)創(chuàng)建Cookie,等價于 response.addHeader("set-cookie", "name=value"); Cookie cookie = new Cookie(String name, String value); // Cookie: name=value cookie.setMaxAge(seconds); // 設(shè)置Cookie的生命周期 cookie.setPath("/"); // 設(shè)置Cookie的共享范圍 response.addCookie(cookie); // 添加1個Cookie
Cookie 獲取:
// 用請求獲取Cookie Cookie[] cookies = request.getCookies(); // 獲取Cookies返回?cái)?shù)組 // 需遍歷 cookie.getName(); // 獲取鍵 cookie.getValue(); // 獲取值
Cookie 修改:
// 修改Cookie cookie.setValue(String name);
1.4 Cookie 共享范圍
/
當(dāng)前項(xiàng)目下所有資源
均可共享訪問該Cookie對象內(nèi)容
/project/demo
當(dāng)前項(xiàng)目下只有資源demo
均可共享訪問該Cookie對象內(nèi)容
設(shè)置 Cookie 數(shù)據(jù)共享范圍:
// 設(shè)置Cookie的共享范圍 cookie.setPath("/");
1.5 Cookie 生命周期
- <0:瀏覽器會話結(jié)束/瀏覽器關(guān)閉,內(nèi)存存儲(
默認(rèn)
) - =0:失效
- >0:生效時間,單位s
在生命周期內(nèi)Cookie會跟隨任何請求,可通過
設(shè)置路徑限制攜帶Cookie的請求資源范圍
。
設(shè)置 Cookie 數(shù)據(jù)生命周期:
// 設(shè)置Cookie生命周期,單位s cookie.setMaxAge(int second); // 7天:7*24*60*60
1.6 Cookie 中文亂碼 - 解決方案
中文:Unicode,4個字節(jié) 英文:ASCII,2個字節(jié)
Cookie的中文亂碼需要進(jìn)行編碼和解碼處理:
編碼:java.net.URLEncoder 的 URLEncoder.encode(String str, String encoding)
解碼:java.net.URLDecoder 的 URLDecoder.decode(String str, String encoding)
// 編碼 Cookie cookie = new Cookie( URLEncoder.encode("鍵", "utf-8"), URLEncoder.encode("值", "utf-8") ); response.addCookie(cookie); // 解碼 String keyStr = URLDecoder.decode(cookie.getName(), "utf-8");
1.7 Cookie 優(yōu)缺特點(diǎn)分析
優(yōu)點(diǎn):
● 可配置到期規(guī)則
:① 1次請求就失效 ②1次瀏覽器會話(關(guān)閉)失效 ③配置永久生效 ● 簡單性
:基于文本的輕量結(jié)構(gòu),簡單鍵值對
● 數(shù)據(jù)持久性
:雖然Cookie可被客戶端瀏覽器的過期處理和干預(yù),但Cookie通常也是客戶端上持續(xù)時間最長的數(shù)據(jù)保留形式缺點(diǎn):
● 大小受到限制
:大多數(shù)瀏覽器的Cookie只有4kb大小的限制
●用戶配置禁用
:客戶瀏覽器設(shè)置了禁用接收Cookie的能力,限制了該功能
● 潛在安全風(fēng)險(xiǎn)
:用戶可能會操縱篡改瀏覽器上的Cookie,會造成Cookie應(yīng)用程序執(zhí)行失敗的問題
2. Cookie 應(yīng)用
2.0 工具類:CookieUtils
public class CookieUtils { /** * 獲取指定名稱的Cookie對象 * @param cookies 一組Cookie * @param cookieName 指定的Cookie名稱 * @return 需要的Cookie */ public static Cookie getCookie(Cookie[] cookies, String cookieName) { if (null != cookies && 0 != cookies.length) { for (Cookie ck : cookies) { if (cookieName.equals(ck.getName())) { return ck; } } } return null; } }
2.1 案例:記錄用戶上一次訪問時間
核心邏輯:
// 判斷是否是第一次請求 Cookie cookie = CookieUtils.getCookie(request.getCookies(), "lastTime"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); if (null == cookie) { // 第一次訪問,打印當(dāng)前時間,并創(chuàng)建Cookie,存儲當(dāng)前時間 Date date = new Date(); System.out.println("第一次訪問時間:" + sdf.format(date)); cookie = new Cookie("lastTime", String.valueOf(date.getTime())); } else { // 不是第一次訪問,從cookie去除上一次訪問時間,并打印,獲取當(dāng)前時間,存儲cookie中 long currTimeMills = Long.parseLong(cookie.getValue()); System.out.println("上一次訪問時間:" + sdf.format(new Date(currTimeMills))); cookie.setValue(String.valueOf((new Date()).getTime())); } response.addCookie(cookie);
2.2 案例:記錄商品的瀏覽歷史信息
歷史記錄核心邏輯:
String id = request.getParameter("id"); Cookie cookie = CookieUtils.getCookie(request.getCookies(), "history"); if (null == cookie) { // 木有瀏覽記錄:創(chuàng)建Cookie,并存儲瀏覽記錄 cookie = new Cookie("history", id); } else { // 有瀏覽記錄 String history = cookie.getValue(); if (!history.contains(id)) { // 有瀏覽記錄,不包含當(dāng)前瀏覽商品:將瀏覽商品拼接到已有的瀏覽記錄中 history += "-" + id; cookie.setValue(history); } // 有瀏覽記錄,包含當(dāng)前瀏覽商品則無需處理 } response.addCookie(cookie); // 顯示商品瀏覽記錄,路徑:/demo/show response.sendRedirect(request.getContextPath() + File.separator + "show");
顯示歷史記錄信息:
// 獲取商品瀏覽記錄 Cookie cookie = CookieUtils.getCookie(request.getCookies(), "history"); StringBuffer respsb = new StringBuffer(); if (null == cookie) { // 沒有瀏覽記錄 respsb.append("<font color='red'>沒有瀏覽記錄</font>,"); respsb.append("<a href='books.html'>瀏覽商品</a>"); } else { // 有瀏覽記錄: 0-1-2-3 String[] books = {"西游記", "紅樓夢", "水滸傳", "三國志"}; String history = cookie.getValue(); String[] historys = history.split("-"); respsb.append("您的瀏覽記錄如下:<br>"); for (String index : historys) { String bookName = books[Integer.parseInt(index)]; respsb.append(bookName).append("<br>"); } } response.setContentType("text/html;charset=utf-8"); response.getWriter().println(respsb);
點(diǎn)擊第一個后:
總結(jié)
本篇文章的內(nèi)容就到這了,希望大家可以多多關(guān)注腳本之家的其他精彩內(nèi)容!
相關(guān)文章
java中stringbuffer線程安全分析實(shí)例詳解
在本篇文章里小編給大家整理的是一篇關(guān)于java中stringbuffer線程安全分析實(shí)例詳解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2021-01-01SpringBoot權(quán)限認(rèn)證-Sa-Token的使用詳解
Sa-Token是一款輕量級Java權(quán)限認(rèn)證框架,它簡化了權(quán)限管理,提高了開發(fā)效率,本文通過實(shí)例介紹了Sa-Token的基本概念、與其他框架的比較、基本語法和高級用法,并探討了其核心原理和實(shí)際應(yīng)用場景,感興趣的朋友一起看看吧2024-09-09Java中的FutureTask實(shí)現(xiàn)代碼實(shí)例
這篇文章主要介紹了Java中的FutureTask手寫代碼實(shí)例,FutureTask是Future的實(shí)現(xiàn),用來異步任務(wù)的獲取結(jié)果,可以啟動和取消異步任務(wù),查詢異步任務(wù)是否計(jì)算結(jié)束以及獲取最終的異步任務(wù)的結(jié)果,需要的朋友可以參考下2023-12-12java代碼規(guī)范之不合理命名與重復(fù)代碼示例詳解
這篇文章主要為大家介紹了java代碼規(guī)范之不合理命名與重復(fù)代碼示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09SWT(JFace)體驗(yàn)之FormLayout布局
SWT(JFace)體驗(yàn)之FormLayout布局示例代碼。2009-06-06Java中的線程池ThreadPoolExecutor深入解析
這篇文章主要介紹了Java中的線程池ThreadPoolExecutor深入解析,線程池,thread pool,是一種線程使用模式,線程池維護(hù)著多個線程,等待著監(jiān)督管理者分配可并發(fā)執(zhí)行的任務(wù),需要的朋友可以參考下2023-11-11解決Intellij IDEA 使用Spring-boot-devTools無效的問題
下面小編就為大家?guī)硪黄鉀QIntellij IDEA 使用Spring-boot-devTools無效的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07