天天看點

談一下cookie和session

最近又學習了一下cookie和session的知識,感覺進步不少,記錄下來,以後忘了的時候也能翻一翻。

談到cookie和session之前,不得不提到另外一個技術,就是會話技術。何為會話,從打開浏覽器通路某個伺服器開始,然後一直通路這個伺服器的web資源,最後關閉浏覽器後,這就是是一次完整會話。特别注意的是,這裡一定是關閉浏覽器之後才是會話的接口,不要了解成關閉标簽頁,關閉标簽頁會話是沒有結束的。會話技術就是記錄用戶端的狀态和資料的,而cookie和session就能實作儲存會話資料。

Cookie,儲存到用戶端浏覽器的會話技術。cookie的構造方法,Cookie cookie = new Cookie(String name,String value)。可以了解成cookie也是鍵值對一樣存在的。cookie.setPath()方法設定cookie的路徑,即通路這個路徑或這個路徑的子路徑才會帶着浏覽器的cookie。cookie.setMaxAge()設定cookie的時間,如果不設定預設的cookie時間是一次會話,即會話結束cookie就不在浏覽器儲存了,設定了時間之後,cookie的過期時間就不再是會話結束了,而是到了設定的時間才過期。了解這些文法後,需要知道兩個問題1.伺服器怎樣獲得用戶端http請求傳來的cookies,隻有一個方法,就是request.getCookies,傳回的是一個cookie資料,想擷取具體name的cookie,需要for循環這個cookie資料,用equals判斷。2.伺服器怎麼傳回一個cookie給用戶端浏覽器呢,這個方法是response.addcookie(cookie)。當使用了構造方法建立出來cookie,并且設定了該cookie的過期時間和路徑之後,添加到response裡就可以傳回給伺服器了。

Session,儲存到伺服器的會話技術。伺服器為每個浏覽器單獨開辟一塊存儲區域,一個使用者打開多個浏覽器通路同一個伺服器,伺服器會各自為浏覽器分别建立屬于浏覽器的session區域,它們的session區域是互不幹擾的。當使用者用戶端浏覽器通路伺服器想儲存資料時,這時候伺服器會把資料儲存到浏覽器對應的session區域中。隻要會話沒有結束,通路伺服器其他程式時也可以拿到這個伺服器的session區域的資料,為使用者提供服務。有個問題來了,伺服器什麼時候建立session?伺服器很智能的,并不是浏覽器随便通路一個伺服器的資源就建立了session,因為這樣太浪費伺服器記憶體了。當第一次調用request.getSession的時候,伺服器會建立session,以後再次調用session的時候,伺服器就不會建立session了,而是擷取這個session。而這些是怎麼實作的呢,内部原理就是   :通路request.getSession的時候,伺服器判斷浏覽器有沒有傳來的鍵為JSESSIONID的cookie,因為第一次通路沒有傳過來JSESSIONID,是以伺服器智能的建立了一個session區域,比如這塊session區域的唯一标示是123456789,建立完了之後會自動傳回浏覽器這個唯一标示,這時候的http響應就變成了

談一下cookie和session

。當浏覽器再次通路伺服器的時候,會帶着這個cookie通路。why,因為這個cookie的路徑是項目名,并且沒有設定cookie的過期時間,代表cookie在會話結束時消失。是以通路這個項目的資源都會帶着這個cookie,再次通路request.getSession的時候,伺服器智能的判斷已經有了session區域了,就不會建立一個新的session給用戶端浏覽器了。說到底為什麼伺服器這個智能判斷已經存在該session了,就是因為第二次之後的浏覽器通路伺服器,都會帶着JSESSIONID這個cookie,伺服器就是根據這個JSESSIONID的cookie判斷用不用建立session。伺服器建立完session傳回給用戶端浏覽器一個JSESSIONID的cookie,和伺服器拿到浏覽器的JSESSIONID的cookie 查詢session區域 這兩個步驟都是伺服器自動完成的,不需要我們操心。說到這裡,其實JSESSIONID的cookie可以了解成一個比較特殊的cookie,它的路徑是項目名,過期時間是會話結束,它是伺服器第一次通路request.getSession的時候自動建立傳回用戶端的。再一次會話内再次通路該項目的其他資源都會帶着這個cookie,伺服器就根據這個cookie來查找到伺服器儲存的session資料。

再提一個問題,如果我們浏覽器清除所有cookie,再次通路伺服器的時候還能找到之前建立的session嗎?答案當然是否定的,因為伺服器就是根據JSESSIONID的cookie查詢session區域的,而清除所有的cookie之後通路伺服器就不帶着JSESSIONID的cookie,肯定找不到伺服器中的session區域了。但是需要注意的是,這個session區域是肯定存在的,至于為什麼存在一會講session的銷毀就知道了,隻是沒有JSESSIONID的cookie,查詢不到這個session區域了。

最後說一個文法問題就是session的生命周期,建立:大家應該都知道了,就是第一次執行request.getSession的時候建立出來的session。銷毀:有三種方式。1.伺服器非正常關閉,這個很好了解 session區域存在伺服器裡,伺服器都關閉了,session區域也沒了。但是為什麼是非正常關閉呢,以為正式關閉可能session區域存在持久化的可能性,這個就不讨論了。2session的預設過期時間是30分鐘,是在tomcat的web.xml中配置的,我們也可以改成1分鐘,那麼session就1分鐘銷毀。這時候又有一個問題,這個過期時間從何時開始計算30分鐘呢?是打開伺服器的時間?還是第一次通路request.getSession?還是退出會話的時候?答案都不是,是從不操作伺服器的web資源開始計時。

3.session.invalidate()方法。

session的作用範圍,預設在一次會話中,也就是說在一次會話中任何資源共用一個session對象。這個也很好了解為什麼是一次會話,因為JSESSIONID的cookie過期時間是會話結束,沒有JSESSIONID,通路伺服器request.getSession的時候伺服器就會判斷出來需要建立一個session區域傳回用戶端浏覽器,而之前的session或許還存在,但是找不到它了,是以session的作用範圍是一次會話,本質就是JSESSIONID的作用範圍是一次會話。

哈哈,第一次釋出文章,希望是個好的開始吧;

繼續閱讀