JavaWeb核心技術(shù)中Session與Cookie淺析
會(huì)話(huà)
會(huì)話(huà):用戶(hù)打開(kāi)瀏覽器進(jìn)行的一系列操作直至關(guān)閉瀏覽器的過(guò)程看作是一次會(huì)話(huà)
HTTP協(xié)議是無(wú)狀態(tài)的,不能實(shí)現(xiàn)跟蹤對(duì)話(huà)。比如進(jìn)入一個(gè)網(wǎng)站,每次操作的請(qǐng)求之間相互獨(dú)立,無(wú)法相互聯(lián)系。也就是說(shuō)你每次請(qǐng)求過(guò)后得到的服務(wù)器響應(yīng)或者數(shù)據(jù)無(wú)法被保存。
跟蹤會(huì)話(huà)的兩種技術(shù):
- 就服務(wù)端來(lái)講,采用Session技術(shù)。服務(wù)器為每一個(gè)用戶(hù)創(chuàng)建了一個(gè)唯一的Session標(biāo)識(shí)用于跟蹤和管理該用戶(hù)的資源。用戶(hù)在下次提交請(qǐng)求時(shí)會(huì)一并提交Session標(biāo)識(shí)用于服務(wù)器識(shí)別然后記錄該用戶(hù)的狀態(tài)
- 客戶(hù)端,Cookie技術(shù)。Cookie也叫做硬盤(pán)Cookie,因?yàn)镃ookie存儲(chǔ)在每一個(gè)客戶(hù)端的硬盤(pán)之上。用戶(hù)在第一次訪問(wèn)服務(wù)器時(shí),由服務(wù)器通過(guò)響應(yīng)頭的方式將用戶(hù)cookie傳遞給瀏覽器。之后的訪問(wèn)會(huì)將請(qǐng)求與cookie一并提交
- 在理解上:Session可以看作是服務(wù)器對(duì)于該用戶(hù)的標(biāo)記,而cookie是位于客戶(hù)端的標(biāo)識(shí),客戶(hù)提交請(qǐng)求時(shí)一并提交cookie,服務(wù)器將會(huì)根據(jù)客戶(hù)的cookie找到對(duì)應(yīng)的session標(biāo)識(shí)從而實(shí)現(xiàn)跟蹤會(huì)話(huà)
當(dāng)用戶(hù)關(guān)閉瀏覽器后,對(duì)應(yīng)的Cookie標(biāo)識(shí)也會(huì)隨即銷(xiāo)毀,但此時(shí)服務(wù)器端session并未失效,只是由于cookie銷(xiāo)毀后無(wú)法繼續(xù)跟蹤用戶(hù)會(huì)話(huà)
Cookie
曲奇餅干
理解為:用戶(hù)的信件 也可以理解為該用戶(hù)的標(biāo)志 由用戶(hù)攜帶
用戶(hù)向服務(wù)器發(fā)送的請(qǐng)求當(dāng)中會(huì)包含該cookie
而瀏覽器也會(huì)根據(jù)該cookie判斷該用戶(hù)是否訪問(wèn)過(guò)本網(wǎng)站從而得知該用戶(hù)的數(shù)據(jù)是否已經(jīng)存在
使用過(guò)的cookie會(huì)保存在本地的用戶(hù)目錄下
cookieAPI
// 上面提到過(guò)用戶(hù)的請(qǐng)求會(huì)攜帶cookie 所以要從客戶(hù)端獲取到cookie Cookie[] cookies = req.getCookies();// --返回Cookie數(shù)組 // 創(chuàng)建cookie 兩個(gè)參數(shù) 鍵name -- 值value Cookie cookie = new Cookie("LoginTimes",System.currentTimeMillis()+""); // 獲取鍵 cookie.getName() // 獲取值 cookie.getValue() // 設(shè)置Cookie有效期 --> 24*60*60表示24小時(shí)*60分鐘*60秒 cookie.setMaxAge(24*60*60); // 響應(yīng)給客戶(hù)端一個(gè)Cookie(信件) resp.addCookie(cookie);
cookie示例–> 瀏覽器顯示用戶(hù)上次的訪問(wèn)時(shí)間
// 參考下方的doGet方法體 { // -- 顯示上次訪問(wèn)的時(shí)間 req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); resp.setHeader("contenttype","text/html;charset=UTF-8"); System.out.println("resp編碼:"+resp.getCharacterEncoding()); System.out.println("req編碼:"+req.getCharacterEncoding()); PrintWriter out = resp.getWriter(); // 從客戶(hù)端獲取Cookie Cookie[] cookies = req.getCookies();// --返回Cookie數(shù)組 // 判斷該用戶(hù)是否已經(jīng)存在Cookie if (cookies!=null){ out.write("LastTime Login Time:"); for (Cookie cookie : cookies) { // 遍歷找到訪問(wèn)時(shí)間的Cookie getName獲得cookie中的鍵 if (cookie.getName().equals("LoginTimes")){ // 獲取LoginTimes-Cookie的值 -- value long l = Long.parseLong(cookie.getValue()); Date date = new Date(l); out.write(date.toLocaleString()); } } } // 記錄本次訪問(wèn)的時(shí)間 --> 新建Cookie Cookie cookie = new Cookie("LoginTimes",System.currentTimeMillis()+""); // 設(shè)置Cookie有效期 --> 24*60*60表示24小時(shí)*60分鐘*60秒 cookie.setMaxAge(24*60*60); // 響應(yīng)給客戶(hù)端一個(gè)Cookie(信件) resp.addCookie(cookie); }
編碼問(wèn)題
如下代碼所示
// setCharacterEncoding意思是在程序中將請(qǐng)求和響應(yīng)均置為utf-8編碼 但是可能瀏覽器會(huì)無(wú)法解析 req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); // 瀏覽器使用的編碼集可能與UTF-8不同 所以此處設(shè)置瀏覽器采用UTF-8編碼 resp.setHeader("content-type","text/html;charset=UTF-8");
但是我們?cè)谙胍筩ookie的值為中文漢字時(shí),建議使用URLEncoder/URLDncoder
// 編碼 URLEncoder.encode("張三","utf-8"); // 解碼 URLDecoder.decode("李四","utf-8");
刪除cookie
/*源碼解析:以秒為單位指定cookie的最大期限;如果否定,則表示未存儲(chǔ)cookie;如果為零,則刪除cookie */ resp.setMaxAge(0);
網(wǎng)頁(yè)中查看cookie
- 首先打開(kāi)瀏覽器頁(yè)面審查元素 選中網(wǎng)絡(luò)
- 在地址欄中執(zhí)行對(duì)應(yīng)操作
- 然后在審查元素->網(wǎng)絡(luò)中會(huì)看到我們的請(qǐng)求數(shù)據(jù)包
- 點(diǎn)擊該數(shù)據(jù)包即可查看所有信息
以上述顯示登錄時(shí)間為例 可以看到此處的Cookie 有一個(gè)LoginTime對(duì)應(yīng)的值
還可以點(diǎn)擊應(yīng)用選中cookie即可查看所有的cookie屬性
Session
會(huì)話(huà)
一個(gè)Session獨(dú)占一個(gè)瀏覽器,一個(gè)瀏覽器對(duì)應(yīng)一個(gè)Session(同一用戶(hù)在不同瀏覽器登錄,使用的session是不同的),瀏覽器未關(guān)閉Session就一直存在
用戶(hù)登錄網(wǎng)站成功之后會(huì)分到一個(gè)SessionID,至此,用戶(hù)在該網(wǎng)站執(zhí)行何種操作都無(wú)需再次登錄,因?yàn)樵谔峤徽?qǐng)求時(shí)服務(wù)器會(huì)識(shí)別用戶(hù)session然后在此session之下響應(yīng)用戶(hù)請(qǐng)求
Session存放在服務(wù)器,用戶(hù)實(shí)際拿到的是SessionID
SessionAPI
// Session對(duì)象 HttpSession session = req.getSession(); // session創(chuàng)建時(shí)間 out.write("創(chuàng)建時(shí)間:"+session.getCreationTime()+"\n"); // sessionID獲取 out.write("SessionID:"+session.getId()+"\n"); // session上次訪問(wèn)時(shí)間 out.write("上次訪問(wèn)時(shí)間:"+session.getLastAccessedTime()+"\n"); // setAttribute設(shè)置鍵值屬性 getAttribute根據(jù)鍵獲取值 // getValue 根據(jù)鍵獲取值-->從2.2開(kāi)始唄getA他tribute替代 // removeAttribute(String name) 刪除name鍵綁定的對(duì)象 如果不存在則不執(zhí)行任何操作 // isNew() 判斷該Session是否為新創(chuàng)建的 //注銷(xiāo)Session session.invalidate(); //注銷(xiāo)Session也會(huì)注銷(xiāo)掉SessionID
Session使用->servlet交互數(shù)據(jù)
Session不僅可以傳輸String類(lèi)型還可以傳輸對(duì)象
// Servlet 1 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 編碼問(wèn)題 req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); resp.setHeader("content-type","text/html;charset:utf-8"); // 流 PrintWriter out = resp.getWriter(); // Session // -- 1.獲取Session對(duì)象 HttpSession session = req.getSession(); // -- 2.獲取SessionID String id = session.getId(); // -- 3.判斷該ID是否存在 if (session.isNew()) { out.write("SessionID已存在:"+id); }else { out.write("Session創(chuàng)建成功,ID:"+id); } out.write("<h1>數(shù)據(jù)已寫(xiě)出,跳轉(zhuǎn)checkData查看</h1>"); // -- 4.寫(xiě)出數(shù)據(jù) session.setAttribute("name","張三"); } // Servlet 2 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 編碼 req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); resp.setHeader("content-type","text/html;charset=UTF-8"); // 獲取數(shù)據(jù) HttpSession session = req.getSession(); String name = (String) session.getAttribute("name"); // 寫(xiě)出數(shù)據(jù) resp.getWriter().write("name:"+name); }
傳輸對(duì)象時(shí)只需將session.setAttribute("鍵", 值)
中的值更改為對(duì)象即可
通過(guò)抓包發(fā)現(xiàn),在用戶(hù)第一次請(qǐng)求時(shí)會(huì)由服務(wù)器創(chuàng)建Session并存儲(chǔ)為cookie的形式(JSESSIONID=你的SessionID),那么當(dāng)用戶(hù)提交請(qǐng)求時(shí)(我們已經(jīng)知道Cookie會(huì)被一起提交),所以此時(shí)服務(wù)器也會(huì)獲取到你的Session,因此你的請(qǐng)求操作都將會(huì)在同一Session中執(zhí)行。等同于服務(wù)器識(shí)別到了你的Session你就擁有了某種權(quán)限
Session與Cookie
Session保存在服務(wù)器端,當(dāng)用戶(hù)量過(guò)多時(shí)就可能會(huì)出現(xiàn)服務(wù)器過(guò)載現(xiàn)象。所以開(kāi)發(fā)時(shí)也需要提前避免,所以通常利用Session+Cookie使用來(lái)減輕服務(wù)器壓力。重要信息保存在Session中,其他信息可以用Cookie保存
Cookie單個(gè)能保存的最大數(shù)據(jù)量為4kb,通常一個(gè)瀏覽器站點(diǎn)只允許存在20個(gè)cookie是把用戶(hù)數(shù)據(jù)寫(xiě)到用戶(hù)瀏覽器,瀏覽器保存
Session是把用戶(hù)數(shù)據(jù)寫(xiě)到用戶(hù)的獨(dú)占Session中
Session相對(duì)于cookie使用頻率更高,更加方便。cookie只能用于存儲(chǔ)字符串(以鍵值對(duì)的形式)并且可存放數(shù)據(jù)有限,而Session可以存儲(chǔ)對(duì)象
到此這篇關(guān)于JavaWeb核心技術(shù)中Session與Cookie淺析的文章就介紹到這了,更多相關(guān)JavaWeb Session Cookie內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JavaWeb使用Session和Cookie實(shí)現(xiàn)登錄認(rèn)證
- Java中Cookie和Session的那些事兒
- Java Web學(xué)習(xí)之Cookie和Session的深入理解
- 基于java中cookie和session的比較
- Java中Cookie和Session詳解及區(qū)別總結(jié)
- JavaWeb詳細(xì)講述Cookie和Session的概念
- Java cookie和session會(huì)話(huà)技術(shù)介紹
- 詳解Javaweb狀態(tài)管理的Session和Cookie
- 深入了解Java中Cookie和Session的區(qū)別
相關(guān)文章
SpringBoot?整合Redis?數(shù)據(jù)庫(kù)的方法
Redis是一個(gè)基于內(nèi)存的日志型可持久化的緩存數(shù)據(jù)庫(kù),保存形式為key-value格式,Redis完全免費(fèi)開(kāi)源,它使用ANSI?C語(yǔ)言編寫(xiě)。這篇文章主要介紹了SpringBoot?整合Redis?數(shù)據(jù)庫(kù)的方法,需要的朋友可以參考下2018-03-03關(guān)于SpingMVC的<context:component-scan>包掃描踩坑記錄
這篇文章主要介紹了關(guān)于SpingMVC的<context:component-scan>包掃描踩坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03淺談Java多線(xiàn)程編程中Boolean常量的同步問(wèn)題
這篇文章主要介紹了淺談Java多線(xiàn)程編程中Boolean常量的同步問(wèn)題,主要針對(duì)線(xiàn)程之間同步了不同的布爾對(duì)象的問(wèn)題,需要的朋友可以參考下2015-10-10詳解SpringBoot中的index首頁(yè)的訪問(wèn)、自定義Favicon圖標(biāo)
這篇文章主要介紹了SpringBoot中的index首頁(yè)的訪問(wèn)、自定義Favicon圖標(biāo),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08Java反射中java.beans包學(xué)習(xí)總結(jié)
本篇文章通過(guò)學(xué)習(xí)Java反射中java.beans包,吧知識(shí)點(diǎn)做了總結(jié),并把相關(guān)內(nèi)容做了關(guān)聯(lián),對(duì)此有需要的朋友可以學(xué)習(xí)參考下。2018-02-02解決java.net.SocketTimeoutException: Read timed out的問(wèn)題
這篇文章主要介紹了解決java.net.SocketTimeoutException: Read timed out的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06@OneToMany查詢(xún)陷入循環(huán)引用的解決方案
這篇文章主要介紹了@OneToMany查詢(xún)陷入循環(huán)引用的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10