首頁 >Java >java教程 >Java servlet之關於session運作原理的圖文程式碼詳解

Java servlet之關於session運作原理的圖文程式碼詳解

黄舟
黄舟原創
2017-07-27 15:22:092594瀏覽

這篇文章主要介紹了servlet之session工作原理簡介,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧

要了解Session的底層運作原理。我們還是先看在一個會話過程中,同一個瀏覽器在訪問多個web資源的情況好了,大致分為以下幾個步驟:

1,瀏覽器訪問某個Servlet ,這時如果伺服器要從請求物件中取得Session物件(第一次取得也是建立),那麼伺服器會為這個Session物件建立一個id:JSESSIONID

2,同時在對瀏覽器的回應過程中,這個Session會將JSESSIONID這個id以Cookie形式回傳給客戶端瀏覽器,記住,這時候Cookie伺服器沒有設定有效時間,因此是存在瀏覽器的快取中,而不是在硬碟檔案。

3,當用戶繼續在這個會話過程中訪問其他Servlet,這時候這個Servlet再從請求對像中獲取Session對象,注意這時候獲取Session對像是從瀏覽器發來的請求中查詢是否有名為JSESSIONID的這個Cookie,如果有,那麼這個Session就不用再創建,而是直接根據查詢伺服器中這個相同JSESSIONID值的Session,換句話說就可以取得之前存在這個Session中的資料。

總結來說,Session是基於Cookie的。

(註:cookie並不是萬能的,Session首先是依據cookie,但是有時候cookie不能用,這時候Session會查詢寄來請求的URL位址是否有JSESSIONID。)

Session的隱藏Cookie,我們可以做個小實驗來驗證下,在【myservlet】這個web工程下創建兩個Servlet,分別命名為SessionDemo1和SessionDemo2:

#在SessionDemo1程式碼為:


   HttpSession session = request.getSession();
   String data = "Message from SessionDemo";
   session.setAttribute("data", data);

在SessionDemo2程式碼為:


   HttpSession session = request.getSession();
   System.out.println((String)session.getAttribute("data"));

我們在瀏覽器中開啟HttpWatch,來存取SessionDemo1,因為是首次造訪Servlet,查看SessionDemo1給瀏覽器的回應:

#確確實實伺服器傳送回瀏覽器有這個JSESSIONID名稱的Cookie,這時候如果我們再在開啟的瀏覽器去存取SessionDemo2,那麼在HttpWatch中觀察請求包的內容發現:

再次造訪伺服器時,瀏覽器就會帶著這個名為JSESSIONID的Cookie給伺服器,伺服器正是透過這個cookie中的JSESSIONID值去伺服器中尋找先前為該瀏覽器所建立的Session。

如果我們將瀏覽器關閉,由於這個cookie沒有設定“setMaxAge”,因此這個cookie只存在於瀏覽器的緩衝,瀏覽器關閉即被銷毀。如果想讓關閉瀏覽器之後,Session還能存在,我們就要人為的覆蓋這個Session的cookie,並設定覆蓋cookie的有效時間和有效路徑。 而這個cookie的值,也就是JSESSIONID的值,可以透過Session的getId()方法得到

1,覆寫有效時間:

注意,伺服器在為瀏覽器建立Session後,在使用者沒有操作的情況下(或瀏覽器關閉後)預設為其維護30分鐘。這點可以從Tomcat的【web.xml】檔案中可以看出:

當然我們也可以從這裡修改伺服器預設的銷毀無操作的Session時間。

當然如果我們不要全域設定所有伺服器中Session的銷毀時間,就在每個web應用中的web.xml檔案中自訂新增2154b31975826eec7c9ecbf8f296fb33和6a21007879b0ac869046665bf2650336進行設定。

註:我們也可以透過Session物件的invalidate()方法,立刻將某個Session銷毀。

對此,如果我們要覆寫一個Session的cookie並保存在硬碟檔案中,我們設定的cookie有效時間就不要超過伺服器預設的session-timeout時間。

2,覆蓋有效路徑:

如果我們創建一個Cookie對象,沒有設定“setPath”,那麼Cookie的有效路徑為創建該Cookie的程式(通常為某個Servlet),即只有訪問了這個程式時瀏覽器才會帶著Cookie過去,那實在是“人脈不通”,訪問這個web應用的其他資源就無法再使用Session了。

我們看看剛才的第一次造訪Servlet時,伺服器為瀏覽器所建立的Session中的cookie的有效路徑:

可以看到这个服务器默认将JSESSIONID这个cookie的有效路径设置为创建这个Session的web工程根目录。所以我们要覆盖Session中的cookie时也应该设置路径为该web工程根目录。

好,接下来对上面那个Servlet的例子进行改造,我们只需要在SessionDemo1中修改就行,因为这个首次将Session的cookie返回给客户端,修改后代码如下:


   HttpSession session = request.getSession();
   String data = "Message from SessionDemo";
   session.setAttribute("data", data);
     
   Cookie cookie = new Cookie("JSESSIONID", session.getId());
   cookie.setMaxAge(30*60);
   cookie.setPath("/myservlet");
   response.addCookie(cookie);

这样,当我们打开浏览器访问了SessionDemo1之后,就能在存放cookie的目录中找到该cookie,如果我们通过HttpWatch来查看可以看到重名的这个cookie:

虽然JSEESIONID这个cookie重名了,没有关系,因为其值都是一样的,并且如果我们将浏览器关闭后,没有设置cookie有效时间的(也是原先Session发来的)cookie将不复存在(存在浏览器缓存中,浏览器关闭就被销毁),这时重新打开一个浏览器,再去访问SessionDemo2依然能获取到原来Session中保存的内容:

注意,这是另外打开浏览器窗口访问的SessionDemo2!!另附:

通过这里我们可以看到,我们人为地将原先Session定义的cookie给替换了,而Session并不知道,只要能获得“JSESSIONID”这个cookie,它就认为cookie是存在的,可以从这个cookie中id值获取以前保存的信息,因此我们实现了一台主机共享一个Session,此时,当浏览器关闭,或者说结束一个会话后,依然能获取Session来获取之前保存的数据。

以上是Java servlet之關於session運作原理的圖文程式碼詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn