面試官:不用背概念,說清楚cookie和session是怎麼交互的?

面試官:不用背概念,說清楚cookie和session是怎麼交互的?

前言

共分為10個章節

1.Java基礎 2.網絡 3.Java併發 4.JVM和JMM 5.數據庫

6.設計模式 7.Linux 8.框架 9.算法 10.工程

本小節屬於Java基礎

介紹

這次先分享單機session,一定用大白話分享清楚,不扯概念。因為我原來面試別人的時候也問這個。被概念的人還是人還是很多的。

Http協議使用的是無狀態連接,這樣會造成什麼問題呢?看如下Demo

面試官:不用背概念,說清楚cookie和session是怎麼交互的?

測試

面試官:不用背概念,說清楚cookie和session是怎麼交互的?

面試官:不用背概念,說清楚cookie和session是怎麼交互的?

HttpServletRequest對象代表客戶端的請求,當客戶端通過HTTP協議訪問服務器時,HTTP請求頭中的所有信息都封裝在這個對象中,當在一個請求中時HttpServletRequest中的信息可以共享,而在不同的請求中HttpServletRequest並不能共享,這樣就會造成用戶確實進行過登錄操作,但是跳到購物車頁面時發現並沒有東西,應為應用並不知道訪問這個頁面的用戶是誰

面試官:不用背概念,說清楚cookie和session是怎麼交互的?

面試官:不用背概念,說清楚cookie和session是怎麼交互的?

對客戶的第一個請求,容器會生成一個唯一的會話ID,並通過響應把它返回給客戶。客戶再在以後的每一個請求中發回這個會話ID。容器看到ID後,就會找到匹配的會話,並把這個會話與請求關聯

面試官:不用背概念,說清楚cookie和session是怎麼交互的?

面試官:不用背概念,說清楚cookie和session是怎麼交互的?

面試官:不用背概念,說清楚cookie和session是怎麼交互的?

果然能保存會話狀態了,客戶和容器如何交換會話ID信息呢?其實是通過cookie實現的

面試官:不用背概念,說清楚cookie和session是怎麼交互的?

面試官:不用背概念,說清楚cookie和session是怎麼交互的?

看上面能保存會話的代碼,我們並沒有對cookie進行操作啊,其實是容器幾乎會做cookie的所有工作,從最開始的Servlet開始講這些操作是如何實現的,先看一下Servlet執行過程

1.用戶點擊頁面發送請求->Web服務器應用(如Apache)->Web容器應用(如tomcat)

2.容器創建兩個對象HttpServletRequest和HttpServletResponse

3.根據URL找到servlet,併為請求創建或分配一個線程,將請求和響應對象傳遞給這個servlet線程

4.容器調用Servlet的service()方法,根據請求的不同類型,service()方法會調用doGet()和doPost()方法,假如請求是HTTP GET請求

5.doGet()方法生成動態頁面,並把這個對象塞到響應對象裡。容器有響應對象的一個引用

6.線程結束,容器把響應對象裝換為一個HTTP請求,把它發回給客戶,然後刪除請求和響應對象

Spring MVC框架其實在Servlet上面封裝了一層,當我們自己用Servlet編寫程序時,可以從HttpServletRequest中獲取HttpSession,如下

面試官:不用背概念,說清楚cookie和session是怎麼交互的?

在響應中發送一個會話cookie

HttpSession session = req.getSession();

我們只需要寫上述一行代碼即可,來看看容器幫我們做了哪些事情

  1. 建立一個新的HttpSession對象
  2. 生成唯一的會話ID
  3. 建立新的Cookie對象
  4. 把會話Id放到cookie中
  5. 在響應中設置cookie

從請求得到會話ID

HttpSession session = req.getSession();
面試官:不用背概念,說清楚cookie和session是怎麼交互的?

如上面用的方法,我們並沒有直接從HttpServletRequest 中獲取HttpSession

能直接獲取到HttpSession,其實是框架幫我們執行了HttpSession session = req.getSession(),然後設置進來的。我們可以設置session的過期時間,以保證用戶登錄後長期不操作需要重新登錄。

tomcat是用如下結構來保存session的

protected Map<string> sessions = new ConcurrentHashMap<string>()
/<string>/<string>

值為會話id,session對象是保存一個會話的各種屬性,就是你調用類似代碼的時候

session.setAttribute("username", username);

可以設置很多個啊,你應該也猜到了,在tomcat中保存會話屬性是用map來保存的

protected Map<string> attributes = new ConcurrentHashMap<string>();
/<string>/<string>

如果我們不自己new cookie而通過req.getSession()來設置cookie,那麼cookie的名字為

JSESSIONID,值為會話id,前面圖片中有哈。

第一次登陸,reponse設置一個cookie( JSESSIONID=會話id)

以後每次登陸帶著這個cookie,通過key為JSESSIONID拿到會話id,因為cookie可以設置很多個哈。

通過JSESSIONID就能拿到session了,拿到session你就能拿出來登陸設置的各種屬性了哈,就能判斷出來這個是哪個用戶了。

概念就不說了,過程還沒明白的可以留言哈。


分享到:


相關文章: