開篇介紹
大家好,我是Java最全面試題庫
的提褲姐
疏虫,今天這篇是JavaWeb系列的第三篇领铐,主要總結(jié)了Java中的Cookie和Session相關(guān)的問題,在后續(xù)荐糜,會沿著第一篇開篇的知識線路一直總結(jié)下去巷怜,做到日更葛超!如果我能做到百日百更,希望你也可以跟著百日百刷延塑,一百天養(yǎng)成一個(gè)好習(xí)慣绣张。
什么是Cookie?
HTTP Cookie(也叫 Web Cookie或?yàn)g覽器 Cookie)是服務(wù)器發(fā)送到用戶瀏覽器并保存在本地的一小塊數(shù)據(jù)关带,它會在瀏覽器下次向同一服務(wù)器再發(fā)起請求時(shí)被攜帶并發(fā)送到服務(wù)器上侥涵。
通常,它用于告知服務(wù)端兩個(gè)請求是否來自同一瀏覽器宋雏,如保持用戶的登錄狀態(tài)芜飘。
Cookie 使基于無狀態(tài)的 HTTP 協(xié)議記錄穩(wěn)定的狀態(tài)信息成為了可能。
什么是 Session磨总?
Session 代表著服務(wù)器和客戶端一次會話的過程嗦明。
Session 對象存儲特定用戶會話所需的屬性及配置信息。這樣蚪燕,當(dāng)用戶在應(yīng)用程序的 Web 頁之間跳轉(zhuǎn)時(shí)娶牌,存儲在 Session 對象中的變量將不會丟失,而是在整個(gè)用戶會話中一直存在下去馆纳。當(dāng)客戶端關(guān)閉會話裙戏,或者 Session 超時(shí)失效時(shí)會話結(jié)束。
Cookie 和 Session 的區(qū)別厕诡?
Cookie
是 web 服務(wù)器發(fā)送給瀏覽器的一塊信息累榜,瀏覽器會在本地一個(gè)文件中給每個(gè) web 服務(wù)器存儲 cookie。以后瀏覽器再給特定的 web 服務(wù)器發(fā)送請求時(shí)灵嫌,同時(shí)會發(fā)送所有為該服務(wù)器存儲的 cookie壹罚。
Session
是存儲在 web 服務(wù)器端的一塊信息。session 對象存儲特定用戶會話所需的屬性及配置信息寿羞。當(dāng)用戶在應(yīng)用程序的 Web 頁之間跳轉(zhuǎn)時(shí)猖凛,存儲在 Session 對象中的變量將不會丟失,而是在整個(gè)用戶會話中一直存在下去绪穆。
區(qū)別:
①存在的位置:
- cookie 存在于客戶端辨泳,臨時(shí)文件夾中;
- session存在于服務(wù)器的內(nèi)存中玖院,一個(gè)session域?qū)ο鬄橐粋€(gè)用戶瀏覽器服務(wù)
②安全性:
- cookie是以明文的方式存放在客戶端的菠红,安全性低,可以通過一個(gè)加密算法進(jìn)行加密后存放难菌;
- session存放于服務(wù)器的內(nèi)存中试溯,所以安全性好
③網(wǎng)絡(luò)傳輸量
- cookie會傳遞消息給服務(wù)器;
- session本身存放于服務(wù)器郊酒,不會有傳送流量
④生命周期(以30分鐘為例)
- cookie的生命周期是累計(jì)的遇绞,從創(chuàng)建時(shí)键袱,就開始計(jì)時(shí),30分鐘后摹闽,cookie生命周期結(jié)束蹄咖;
- session的生命周期是間隔的,從創(chuàng)建時(shí)付鹿,開始計(jì)時(shí)如在30分鐘澜汤,沒有訪問session,那么session生命周期被銷毀倘屹。但是,如果在30分鐘內(nèi)(如在第29分鐘時(shí))訪問過session慢叨,那么纽匙,將重新計(jì)算session的生命周期。關(guān)機(jī)會造成session生命周期的結(jié)束拍谐,但是對cookie沒有影響烛缔。
⑤訪問范圍
- cookie為多個(gè)用戶瀏覽器共享;
- session為一個(gè)用戶瀏覽器獨(dú)享
簡單來說cookie機(jī)制采用的是在客戶端保持狀態(tài)的方案轩拨,
而session機(jī)制采用的是在服務(wù)器端保持狀態(tài)的方案践瓷。
由于才服務(wù)器端保持狀態(tài)的方案在客戶端也需要保存一個(gè)標(biāo)識,所以session機(jī)制可能需要借助于cookie機(jī)制來達(dá)到保存標(biāo)識的目的亡蓉。
如何利用實(shí)現(xiàn)自動登錄晕翠?
當(dāng)用戶在某個(gè)網(wǎng)站注冊后,就會收到一個(gè)唯一用戶ID的cookie砍濒×苌觯客戶后來重新連接時(shí),這個(gè)用戶ID會自動返回爸邢,服務(wù)器對它進(jìn)行檢查樊卓,確定它是否為注冊用戶且選擇了自動登錄,從而使用戶務(wù)需給出明確的用戶名和密碼杠河,就可以訪問服務(wù)器上的資源碌尔。
如何獲取Cookie?
1券敌、調(diào)用request.getCookie
2唾戚、對數(shù)組進(jìn)行循環(huán),調(diào)用每個(gè)cookie的getName
方法
session的機(jī)制
session機(jī)制是一種服務(wù)器端
的機(jī)制待诅,服務(wù)器使用一種類似于散列表的結(jié)構(gòu)(也可能就是使用散列表)來保存信息颈走。
但程序需要為某個(gè)客戶端的請求創(chuàng)建一個(gè)session的時(shí)候,服務(wù)器首先檢查這個(gè)客戶端的請求里是否包含了一個(gè)session標(biāo)識咱士,稱為session id立由;如果已經(jīng)包含一個(gè)session id則說明以前已經(jīng)為此客戶創(chuàng)建過session轧钓,服務(wù)器就按照session id把這個(gè)session檢索出來使用(如果檢索不到,可能會新建一個(gè)锐膜,這種情況可能出現(xiàn)在服務(wù)端已經(jīng)刪除了該用戶對應(yīng)的session對象毕箍,但用戶人為地在請求的URL后面附加上一個(gè)JSESSION
的參數(shù))。
如果客戶請求不包含session id
道盏,則為此客戶創(chuàng)建一個(gè)session并且生成一個(gè)與此session相關(guān)聯(lián)的session id而柑,這個(gè)session id將在本次響應(yīng)中返回給客戶端保存。
Cookie的過期和Session的超時(shí)有什么區(qū)別?
Cookie的過期和Session的超時(shí)(過期)荷逞,都是對某個(gè)對象設(shè)置一個(gè)時(shí)間媒咳,然后采用輪訓(xùn)機(jī)制(或者首次訪問時(shí))檢查當(dāng)前對象是否超時(shí)(當(dāng)前對象會保存一個(gè)開始時(shí)間),如果超時(shí)則進(jìn)行移除种远。
cookie保存在瀏覽器中涩澡,不安全。而session是保存在服務(wù)端的坠敷。cookie的生命周期很長妙同,而session很短,一般也就幾十分鐘膝迎。
cookie是保存在客戶端粥帚,session保存在服務(wù)器端,cookie保存著session相關(guān)信息限次。
如果cookie沒有超時(shí)芒涡,那么瀏覽器每次請求都會帶上該cookie信息,服務(wù)器端根據(jù)cookie信息從session緩存中獲取相對應(yīng)的session卖漫。這兩個(gè)信息有一個(gè)超時(shí)拖陆,用戶連接即宣告關(guān)閉。
會話的超時(shí)由服務(wù)器來維護(hù)懊亡,它不同于Cookie的失效日期依啰。
首先,會話一般基于駐留內(nèi)存的cookie店枣,不是持續(xù)性的cookie喝滞,因而也就沒有截至日期菩混。
即使截取到JSESSIONID cookie夏跷,并為它設(shè)定一個(gè)失效日期發(fā)送出去蓉冈。瀏覽器會話和服務(wù)器會話也會截然不同。
如何解決分布式 Session 問題钧唐?
-
Nginx ip_hash策略
忙灼,服務(wù)端使用 Nginx 代理,每個(gè)請求按訪問 IP 的 hash 分配,這樣來自同一 IP 固定訪問一個(gè)后臺服務(wù)器该园,避免了在服務(wù)器 A 創(chuàng)建 Session酸舍,第二次分發(fā)到服務(wù)器 B 的現(xiàn)象。 -
Session 復(fù)制
里初,任何一個(gè)服務(wù)器上的 Session 發(fā)生改變(增刪改)啃勉,該節(jié)點(diǎn)會把這個(gè) Session 的所有內(nèi)容序列化,然后廣播給所有其它節(jié)點(diǎn)双妨。 -
共享 Session
淮阐,服務(wù)端無狀態(tài)話,將用戶的 Session 等信息使用緩存中間件來統(tǒng)一管理刁品,保障分發(fā)到每一個(gè)服務(wù)器的響應(yīng)結(jié)果都一致泣特。
在單點(diǎn)登錄中,如果 cookie 被禁用了怎么辦挑随?
單點(diǎn)登錄的原理是后端生成一個(gè) session ID
状您,然后設(shè)置到 cookie
,后面的所有請求瀏覽器都會帶上 cookie镀裤,然后服務(wù)端從 cookie 里獲取 session ID竞阐,再查詢到用戶信息缴饭。
所以暑劝,保持登錄的關(guān)鍵不是 cookie,而是通過cookie 保存和傳輸?shù)?session ID颗搂,其本質(zhì)是能獲取用戶信息的數(shù)據(jù)担猛。
除了 cookie,還通常使用 HTTP 請求頭來傳輸丢氢。但是這個(gè)請求頭瀏覽器不會像 cookie 一樣自動攜帶傅联,需要手工處理。
session何時(shí)被刪除疚察?
session在下列情況下被刪除:
- 程序調(diào)用
HttpSession.invalidate()
- 距離上一次收到客戶端發(fā)送的
session id
時(shí)間間隔超過了session的最大有效時(shí)間
- 服務(wù)器進(jìn)程被停止
注意關(guān)閉瀏覽器只會使存儲在客戶端瀏覽器內(nèi)存中的session cookie失效蒸走,不會使服務(wù)器端的session對象失效。