1. 程式人生 > >【小家java】Session和Cookie的區別和聯絡、分散式session的幾種實現方式

【小家java】Session和Cookie的區別和聯絡、分散式session的幾種實現方式

相關閱讀

【小家java】java5新特性(簡述十大新特性) 重要一躍
【小家java】java6新特性(簡述十大新特性) 雞肋升級
【小家java】java7新特性(簡述八大新特性) 不溫不火
【小家java】java8新特性(簡述十大新特性) 飽受讚譽
【小家java】java9新特性(簡述十大新特性) 褒貶不一
【小家java】java10新特性(簡述十大新特性) 小步迭代
【小家java】java11新特性(簡述八大新特性) 首個重磅LTS版本


session和cookie兩個概念,在web開發是經常被提及到的兩個概念。它們之間有聯絡也有區別,那麼本文主要解惑一些咱們平時挺關心的一些區別:

Session和Cookie的區別和聯絡

區別
  1. session儲存在伺服器,客戶端不知道其中的資訊;cookie儲存在客戶端,伺服器能夠知道其中的資訊
  2. session中儲存的是物件,cookie中儲存的是字串
  3. session不能區分路徑,同一個使用者在訪問一個網站期間,所有的session在任何一個地方都可以訪問到。而cookie中如果設定了路徑引數,那麼同一個網站中不同路徑下的cookie互相是訪問不到的。
  4. session需要藉助cookie才能正常。
聯絡

http是無狀態的協議,客戶每次讀取web頁面時,伺服器都開啟新的會話,而且伺服器也不會自動維護客戶的上下文資訊,那麼要怎麼才能實現網上商店中的購物車呢?
session就是一種儲存上下文資訊的機制,它是針對每一個使用者的,變數的值儲存在伺服器端,通過SessionID來區分不同的客戶

,session是以cookie或URL重寫為基礎的,預設使用cookie來實現,系統會創造一個名為JSESSIONID的輸出cookie,我們叫做session cookie,以區別persistent cookies,也就是我們通常所說的cookie,注意session cookie是儲存於瀏覽器記憶體中的,並不是寫到硬碟上的,這也就是我們剛才看到的JSESSIONID,我們通常情是看不到JSESSIONID的,但是當我們把瀏覽器的cookie禁止後,web伺服器會採用URL重寫的方式傳遞Sessionid,我們就可以在位址列看到 sessionid=KWJHUG6JJM65HS2K6之類的字串。

通常session cookie是不能跨視窗使用的,當你新開了一個瀏覽器視窗進入相同頁面時,系統會賦予你一個新的sessionid,這樣我們資訊共享的目的就達不到了,此時我們可以先把sessionid儲存在persistent cookie中,然後在新視窗中讀出來,就可以得到上一個視窗SessionID了,這樣通過session cookie和persistent cookie的結合我們就實現了跨視窗的session tracking(會話跟蹤)。

針對上述區別和聯絡,衍生出來的一些面試題如下:

  • cookie機制和session機制的區別?
    具體來說cookie機制採用的是在客戶端保持狀態的方案,而session機制採用的是在伺服器端保持狀態的方案。
      同時我們也看到,由於在伺服器端保持狀態的方案在客戶端也需要儲存一個標識,所以session機制可能需要藉助於cookie機制來達到儲存標識的目的,但實際上還有其他選擇。
  • 會話cookie和持久cookie的區別?
    如果不設定過期時間,則表示這個cookie生命週期為瀏覽器會話期間,只要關閉瀏覽器視窗,cookie就消失了。這種生命期為瀏覽會話期的cookie被稱為會話cookie。會話cookie一般不儲存在硬碟上而是儲存在記憶體裡。

如果設定了過期時間,瀏覽器就會把cookie儲存到硬碟上,關閉後再次開啟瀏覽器,這些cookie依然有效直到超過設定的過期時間。

儲存在硬碟上的cookie可以在不同的瀏覽器程序間共享,比如兩個IE視窗。而對於儲存在記憶體的cookie,不同的瀏覽器有不同的處理方式。

  • 如何實現自動登入?
    當用戶在某個網站註冊後,就會收到一個惟一使用者ID的cookie。客戶後來重新連線時,這個使用者ID會自動返回,伺服器對它進行檢查,確定它是否為註冊使用者且選擇了自動登入,從而使使用者無需給出明確的使用者名稱和密碼,就可以訪問伺服器上的資源。
  • 如何根據使用者的愛好定製站點?
    網站可以使用cookie記錄使用者的意願。對於簡單的設定,網站可以直接將頁面的設定儲存在cookie中完成定製。然而對於更復雜的定製,網站只需僅將一個惟一的識別符號傳送給使用者,由伺服器端的資料庫儲存每個識別符號對應的頁面設定。
  • 服務端cookie的傳送,如何傳送?
    1.建立Cookie物件
    2.設定最大時效(maxAge)
    3.將Cookie放入到HTTP響應報頭
    傳送cookie需要使用HttpServletResponse的addCookie方法,將cookie插入到一個 Set-Cookie HTTP請求報頭中。由於這個方法並不修改任何之前指定的Set-Cookie報頭,而是建立新的報頭,因此我們將這個方法稱為是addCookie,而非setCookie。同樣要記住響應報頭必須在任何文件內容傳送到客戶端之前設定。
  • 服務端cookie的讀取,如何獲取?
    要獲取有瀏覽器傳送來的cookie,需要呼叫HttpServletRequest的getCookies方法,這個呼叫返回Cookie物件的陣列,對應由HTTP請求中Cookie報頭輸入的值。
String cookieName = “userID”;
Cookie cookies[] = request.getCookies();
if (cookies!=null){
	for(int i=0;i <= cookies.length(),i++){
	 	Cookie cookie = cookies[i];
		if (cookieName.equals(cookie.getName())){
			doSomethingWith(cookie.getValue());
		}
	}
}
  • 如何使用cookie檢測初訪者?
    檢索指定名字的cookie是否存在以及對應值是否正確。如果存在就設定一個值告訴cookie,表示上是初訪者即可
  • 使用cookie檢測初訪者的常見錯誤?
    不能僅僅因為cookie陣列中不存在在特定的資料項就認為使用者是個初訪者。如果cookie陣列為null,客戶可能是一個初訪者,也可能是由於使用者將cookie刪除或禁用造成的結果。

但是,如果陣列非null,也不過是顯示客戶曾經到過你的網站或域,並不能說明他們曾經訪問過你的servlet。其它servlet、JSP頁面以及非Java Web應用都可以設定cookie,依據路徑的設定,其中的任何cookie都有可能返回給使用者的瀏覽器。

正確的做法是判斷cookie陣列是否為空且是否存在指定的Cookie物件且值正確。

  • 如何使用cookie記錄各個使用者的訪問計數?
    1.獲取cookie陣列中專門用於統計使用者訪問次數的cookie的值
    2.將值轉換成int型
    3.將值加1並用原來的名稱重新建立一個Cookie物件
    4.重新設定最大時效
    5.將新的cookie輸出
  • 儲存session id的幾種方式?
    A.儲存session id的方式可以採用cookie,這樣在互動過程中瀏覽器可以自動的按照規則把這個標識傳送給伺服器。
    B.由於cookie可以被人為的禁止,必須有其它的機制以便在cookie被禁止時仍然能夠把session id傳遞迴伺服器,經常採用的一種技術叫做URL重寫,就是把session id附加在URL路徑的後面,附加的方式也有兩種,一種是作為URL路徑的附加資訊,另一種是作為查詢字串附加在URL後面。網路在整個互動過程中始終保持狀態,就必須在每個客戶端可能請求的路徑後面都包含這個session id。
    C.另一種技術叫做表單隱藏欄位。就是伺服器會自動修改表單,新增一個隱藏欄位,以便在表單提交時能夠把session id傳遞迴伺服器。
  • session什麼時候被建立?
    request.getSession()和request.getSession(true)意思相同:獲取session,如果session不存在,就新建一個。
    當向Session中存取登入資訊時,一般建議:HttpSession session =request.getSession();
    當從Session中獲取登入資訊時,一般建議:HttpSession session =request.getSession(false);
  • session何時被刪除?
    A.程式呼叫HttpSession.invalidate()
    B.距離上一次收到客戶端傳送的session id時間間隔超過了session的最大有效時間
    C.伺服器程序被停止

再次注意關閉瀏覽器只會使儲存在客戶端瀏覽器記憶體中的session cookie失效,不會使伺服器端的session物件失效。

分散式Session的幾種實現方式

1、基於資料庫的Session共享
2、基於NFS共享檔案系統
3、基於memcached / redis等集中式快取的session共享(常用)

  • 簡介:將Session存入分散式快取叢集中的某臺機器上,當用戶訪問不同節點時先從快取中拿Session資訊
  • 使用場景:叢集中機器數多、網路環境複雜
  • 優點:可靠性好
  • 缺點:實現複雜、穩定性依賴於快取的穩定性、Session資訊放入快取時要有合理的策略寫入
    4、基於tomcat web容器本身的session複製機制
  • 簡介:將一臺機器上的Session資料廣播複製到叢集中其餘機器上
  • 使用場景:機器較少,網路流量較小
  • 優點:實現簡單、配置較少、當網路中有機器Down掉時不影響使用者訪問
  • 缺點:廣播式複製到其餘機器有一定廷時,帶來一定網路開銷
    5、基於cookie 進行session共享
  • 實現簡單,但是不夠安全。內部管理系統獲取可以快速這麼搭建

最後,在rest風格程式設計大行其道的今天,其實都不會再有session的概念了,統一使用JWT來實現統一鑑權和資訊儲存