會話:用戶開一個浏覽器,點擊多個超鏈接,訪問服務器多個web資源,然後關閉浏覽器,整個過程稱之為一個會話
Cookie
Cookie是客戶端技術,程序把每個用戶的數據以cookie的形式寫給用戶各自的浏覽器。當用戶使用浏覽器再去訪問服務器中的web資源時,就會帶著各自的數據去。這樣,web資源處理的就是用戶各自的數據了。
Cookie存儲位置
如果設置了Expires過期時間,那Cookie存儲在硬盤上,如果沒有設置,則存儲在內存中,隨著浏覽器的關閉而消亡。
Win7上Cookies硬盤上的位置:
Cookie: C:/Users/[user name]/AppData/Roaming/Microsoft/Windows/Cookies/
C:/Users/[user name]/AppData/Roaming/Microsoft/Windows/Cookies/Low/
其中的部分文件夾,操作系統給隱藏掉了,可直接輸入地址來查找。
HttpSession
Session是服務器端技術,利用這個技術,服務器在運行時可以為每一個用戶的浏覽器創建一個其獨享的HttpSession對象,由於session為用戶浏覽器獨享,所以用戶在訪問服務器的web資源時,可以把各自的數據放在各自的session中,當用戶再去訪問服務器中的其它web資源時,其它web資源再從用戶各自的session中取出數據為用戶服務。
在WEB開發中,服務器可以為每個用戶浏覽器創建一個會話對象(session對象),注意:一個浏覽器獨占一個session對象(默認情況下)。因此,在需要保存用戶數據時,服務器程序可以把用戶數據寫到用戶浏覽器獨占的session中,當用戶使用浏覽器訪問其它程序時,其它程序可以從用戶的session中取出該用戶的數據,為用戶服務。 Session和Cookie的主要區別在於: Cookie是把用戶的數據寫給用戶的浏覽器。 Session技術把用戶的數據寫到用戶獨占的session中。 Session對象由服務器創建,開發人員可以調用request對象的getSession方法得到session對象。
Java Servlet中的域對象
request,response對象針對每個用戶的每次請求:每次請求都會重新創建這兩個對象,所以這兩個對象不能存儲全局變量,可以用到的地方是請求轉發,可以將本次請求的request對象傳遞到下一次。
Servlet,ServletContext對象針對所有用戶的所有請求,網站的第一個人訪問的時候就會創建這些對象,之後會一直存在,知道服務器關閉。所以ServletContext可以存儲全局信息,但是是針對所有用戶的,比如網站訪問量計數功能就可以使用該對象。缺點是所有對象都可以訪問到。
Cookie,Session對象針對每個用戶的所有請求,當我們使用request.getSession()得到HttpSession對象時,服務器就會為它分配一個ID,然後每個用戶自己的信息就存放到了不同的HttpSession對象中,響應返回,服務器將用戶Session對象的ID以Cookie形式來保存,例如:
Cookie:JSESSIONID=2DB77EDB2964DFC61828ECBCC8076258
這樣,浏覽器每次請求服務器都會帶上此Cookie來告訴服務器,嗨,老兄,ID為這個的HttpSession對象是我的,我要取出裡面的信息。
流程:
1 第一次訪問服務器的時候,會在響應頭裡面看到Set-Cookie信息(只有在首次訪問服務器的時候才會在響應頭中出現該信息)
2 以後的每次請求,請求頭中都會有此Cookie發給服務器
問題:
Session默認是需要Cookie支持的,但有些客戶浏覽器是關閉Cookie的,那我們是不是就無法使用Session了?
解決:
URL重寫功能,為了防止一些用戶把Cookie禁止而無法使用session而設置的功能。當檢測到浏覽器禁用Cookie時,將sessionid添加到URL後面,以此實現傳到服務端的目的,這樣無需cookie也可以使用session.
形式:
http://localhost/Web/B;jsessionid=2DB77EDB2964DFC61828ECBCC8076258?name=zz
jessionid通過這樣的方式來從客戶端傳遞到服務器端,從而來標識session。注意一點,jsessionid跟一般的url參數傳遞方式是不同的,不是作為參數跟在?後面,而是緊跟在url後面用;來分隔。這樣在用戶禁用cookie的時候我們也可以傳遞jsessionid來使用session了.
Session非活動時間:默認30分鐘失效。
void setMaxInactiveInterval(int interval);
網站退出時應銷毀所有Session。
void invalidate();
getSession()內部執行原理:
第一次request.getSession(),創建本次會話對象。
每次請求的request對象不同,但是request.getSession()得到的會話對象是同一個。
問題:
服務器如何判斷getSession()是創建還是得到?
解決:
當創建了會話對象,服務端添加Cookie:sessionId=值,以後浏覽器的請求都會帶著這個Cookie,服務端以此Cookie來判斷它是否已經創建了會話對象。
注意:
這裡的sessionId只是個概念,寓意:標識會話的唯一值,在Tomcat中是JSESSIONID,在其它服務器,框架可能設置其它名字。
request.getSession()等價於request.getSession(true),true的意思為:已經存在Session對象了,返回已存在對象。如果沒有Session對象,則會創建新對象。
序列化:
Tomcat的Work工作目錄存儲對象序列化,存儲到了SESSION.ser文件。
在HttpSession中存儲的對象應該實現序列化接口,這樣當服務器關閉,在重啟之後,HttpSession中的數據也不會消失。