jsessionid是什么?cookie session 終於明白了


Jsessionid子的就是sessionid,Tomcat中生成的就是叫做jsessionid。

 

瀏覽器第一次訪問服務器會在服務器端生成一個session,這個session保存的是瀏覽器的相關信息。有一個sessionid和這個session對應,tomcat的StandardManager類將session存儲在內存中,也可以持久化到文件。 

客戶端只保存sessionid到cookie上,而不保存session,session銷毀只能通過invalidate或超時。關掉瀏覽器並不會關閉session。

 

可以概括出,sessionid是服務器產生的一個會話key,用來維持這個會話,但是瀏覽器可以保持這個會話。當瀏覽器關閉,或者超過會話時間,sessionid就會丟失,session保存的數據也就對之前的客戶端來說--消失了,找不到了。

 

session在訪問tomcat服務器HttpServletRequest的getSession(true)的時候創建,tomcat的ManagerBase類提供創建sessionid的方法:隨機數+時間+jvmid;

存儲在服務器的內存中,tomcat的StandardManager類將session存儲在內存中,也可以持久化到file,數據庫,memcache,redis等。客戶端只保存sessionid到cookie中,而不會保存session,session銷毀只能通過invalidate或超時,關掉瀏覽器並不會關閉session。

那么Session在何時創建呢?當然還是在服務器端程序運行的過程中創建的,不同語言實現的應用程序有不同創建Session的方法,而在Java中是通過調用HttpServletRequest的getSession方法(使用true作為參數)創建的。在創建了Session的同時,服務器會為該Session生成唯一的Session id,而這個Session id在隨后的請求中會被用來重新獲得已經創建的Session;在Session被創建之后,就可以調用Session相關的方法往Session中增加內容了,而這些內容只會保存在服務器中,發到客戶端的只有Session id;當客戶端再次發送請求的時候,會將這個Session id帶上,服務器接受到請求之后就會依據Session id找到相應的Session,從而再次使用之。

 

創建:sessionid第一次產生是在直到某server端程序調用 HttpServletRequest.getSession(true)這樣的語句時才被創建。

刪除:超時;程序調用HttpSession.invalidate();程序關閉;

session存放在哪里:服務器端的內存中。不過session可以通過特殊的方式做持久化管理(memcache,redis)。

session的id是從哪里來的,sessionID是如何使用的:當客戶端第一次請求session對象時候,服務器會為客戶端創建一個session,並將通過特殊算法算出一個session的ID,用來標識該session對象

session會因為瀏覽器的關閉而刪除嗎?
不會,session只會通過上面提到的方式去關閉。
 
 
下面是tomcat中session的創建:
ManagerBase是所有session管理工具類的基類,它是一個抽象類,所有具體實現session管理功能的類都要繼承這個類,該類有一個受保護的方法,該方法就是創建sessionId值的方法:
( tomcat的session的id值生成的機制是一個隨機數加時間加上jvm的id值,jvm的id值會根據服務器的硬件信息計算得來,因此不同jvm的id值都是唯一的),
StandardManager類是tomcat容器里默認的session管理實現類,
它會將session的信息存儲到web容器所在服務器的內存里。
PersistentManagerBase也是繼承ManagerBase類,它是所有持久化存儲session信息的基類,PersistentManager繼承了PersistentManagerBase,但是這個類只是多了一個靜態變量和一個getName方法,目前看來意義不大, 對於持久化存儲session,tomcat還提供了StoreBase的抽象類,它是所有持久化存儲session的基類,另外tomcat還給出了文件存儲FileStore和數據存儲JDBCStore兩個實現。

 

所以會出現以下三種情況:

1、server沒有關閉,並在session對象銷毀時間內,當客戶端再次來請求serve端的servlet或jsp時,將會把將第一次請求該serve時生成的sessionid帶到請求頭上向server端發送,server端收到sessionid后根據此sessionid會去搜索server對應的session對象並直接返回這個session對象,此時不會重新創建session對象。

 

2、當server關閉(之前產生的session對象也就消亡了),或者session對象過了銷毀時間,瀏覽器窗口沒有關閉,並在本窗口繼續請求server端的servlet或者jsp時,此時同樣會將sessionid 發送到 服務端,server拿着id去找對應的session對象;但是此時session對象已經不存在了。所以會重新生成一個session和對應的sessionid ,將這個新的id以響應報文的形式發到瀏覽器的內核中,重新更新cookie。

 

3、當server沒有關閉,並且session對象在其銷毀時間內,當請求一個jsp頁面返回客戶端后,關閉此瀏覽器窗口,此時其內存中的sessionid也就隨之銷毀。在重新去請求server端的servlet或者jsp時,會重新生成一個sessionid給客戶端瀏覽器,並且存在瀏覽器內存中。

 

cookie的保存方式有兩種:

 

如果沒有設置cookie的失效時間,這個cookie就存在與瀏覽器進程;

設置了cookie的失效時間,那么這個cookie就存在於硬盤。

        //Cookie的一些基本設置
        Cookie cookie = new Cookie("Admin-Token", token);

        Cookie[] cookie2 = request.getCookies();
        //request.getContextPath()   mdrwebrest
        cookie.setPath("/");        //設置cookies有效路徑
        //設置cookie有效時間  正數:存到硬盤,負數存到瀏覽器,0立刻銷毀
        cookie.setMaxAge();      
        cookie.setDomain(loginToMDRConfig.getIP()); //跨域
        response.addCookie(cookie);

 

 

當將sessionid保存在硬盤時,可以在打開瀏覽器時指定先攜帶jsessionID去找服務端的session,可以看下邊的一個案例。

 

 

 

 

下邊是看到一個網上的案例,記一下他的解決思路

 

最近碰到一個問題,統計在線人數,初步想法能將session管理起來,即可達成目的,但是發現直接關閉瀏覽器,session竟找不到登錄用戶了,難道關閉瀏覽器,session就銷毀了?不是這樣的

 

session的運行機制

  • 當一個Session開始時,Servlet容器會創建一個HttpSession對象,那么在HttpSession對象中,可以存放用戶狀態的信息

  • Servlet容器為HttpSession對象分配一個唯一標識符即Sessionid,Servlet容器把Sessionid作為一種Cookie保存在客戶端的 *瀏覽器* 中

  • 用戶每次發出Http請求時,Servlet容器會從HttpServletRequest對象中取出Sessionid,然后根據這個Sessionid找到相應的HttpSession對象,從而獲取用戶的狀態信息

 

為什么當我們關閉瀏覽器后,就再也訪問不到之前的session了呢?

 

其實之前的Session一直都在服務器端,而當我們關閉瀏覽器時,此時的Cookie是存在

 

於瀏覽器的進程中的,當瀏覽器關閉時,Cookie也就不存在了。

 

其實Cookie有兩種:

 

  • 一種是存在於瀏覽器的進程中;
  • 一種是存在於硬盤上

 

而session的Cookie是存在於瀏覽器的進程中,那么這種Cookie我們稱為會話Cookie,

 

當我們重新打開瀏覽器窗口時,之前的Cookie中存放的Sessionid已經不存在了,此時

 

服務器從HttpServletRequest對象中沒有檢查到sessionid,服務器會再發送一個新的存

 

有Sessionid的Cookie到客戶端的瀏覽器中,此時對應的是一個新的會話,而服務器上

 

原先的session等到它的默認時間到之后,便會自動銷毀。

 

以上既是為何找不到session的原因,如何解決?

可以在登錄的時候,手動把JSESSIONID保存到COOKIE中,並令其存在的生命周期更長(可以和session的生命周期保持一致),這樣即使瀏覽器關閉,cookie也不會消失,JSESSIONID還在,服務器即可再找到該session,具體代碼如下:

 

 

HttpSession session=request.getSession(); //獲取session
String sessionid=session.getId();  //獲取sessionid
Cookie cookie=new Cookie("JSESSIONID",sessionid); //手動設置一個硬盤存儲COOKIE,這個cooike時存在硬盤的,不是存在瀏覽器線程的
cookie.setMaxAge(30*60);
response.addCookie(cookie); //將COOKIE設置到響應上

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM