這篇文章主要介紹了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中文網其他相關文章!