前言
共分為10個章節
1.Java基礎 2.網絡 3.Java併發 4.JVM和JMM 5.數據庫
6.設計模式 7.Linux 8.框架 9.算法 10.工程
本小節屬於Java基礎
介紹
這次先分享單機session,一定用大白話分享清楚,不扯概念。因為我原來面試別人的時候也問這個。被概念的人還是人還是很多的。
Http協議使用的是無狀態連接,這樣會造成什麼問題呢?看如下Demo
測試
HttpServletRequest對象代表客戶端的請求,當客戶端通過HTTP協議訪問服務器時,HTTP請求頭中的所有信息都封裝在這個對象中,當在一個請求中時HttpServletRequest中的信息可以共享,而在不同的請求中HttpServletRequest並不能共享,這樣就會造成用戶確實進行過登錄操作,但是跳到購物車頁面時發現並沒有東西,應為應用並不知道訪問這個頁面的用戶是誰
對客戶的第一個請求,容器會生成一個唯一的會話ID,並通過響應把它返回給客戶。客戶再在以後的每一個請求中發回這個會話ID。容器看到ID後,就會找到匹配的會話,並把這個會話與請求關聯
果然能保存會話狀態了,客戶和容器如何交換會話ID信息呢?其實是通過cookie實現的
看上面能保存會話的代碼,我們並沒有對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
HttpSession session = req.getSession();
我們只需要寫上述一行代碼即可,來看看容器幫我們做了哪些事情
- 建立一個新的HttpSession對象
- 生成唯一的會話ID
- 建立新的Cookie對象
- 把會話Id放到cookie中
- 在響應中設置cookie
從請求得到會話ID
HttpSession session = req.getSession();
如上面用的方法,我們並沒有直接從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你就能拿出來登陸設置的各種屬性了哈,就能判斷出來這個是哪個用戶了。
概念就不說了,過程還沒明白的可以留言哈。
閱讀更多 Java識堂 的文章