轉載:原文鏈接
http://www.cnblogs.com/lyy-5518/p/5460994.html
一冗茸、什么是http session,有什么用
HTTP協(xié)議本身是無狀態(tài)的,本身并不能支持服務端保存客戶端的狀態(tài)信息罕模,于是溯街,Web Server中引入了session的概念诱桂,用來保存客戶端的狀態(tài)信息。
這 里用一個形象的比喻來解釋session的工作方式呈昔。假設Web Server是一個商場的存包處挥等,HTTP Request是一個顧客,第一次來到存包處堤尾,管理員把顧客的物品存放在某一個柜子里面(這個柜子就相當于Session)肝劲,然后把一個號碼牌交給這個顧 客,作為取包憑證(這個號碼牌就是Session ID)郭宝。顧客(HTTP Request)下一次來的時候辞槐,就要把號碼牌(Session ID)交給存包處(Web Server)的管理員。管理員根據(jù)號碼牌(Session ID)找到相應的柜子(Session)粘室,根據(jù)顧客(HTTP Request)的請求榄檬,Web Server可以取出、更換衔统、添加柜子(Session)中的物品鹿榜,Web Server也可以讓顧客(HTTP Request)的號碼牌和號碼牌對應的柜子(Session)失效先朦。顧客(HTTP Request)的忘性很大,管理員在顧客回去的時候(HTTP Response)都要重新提醒顧客記住自己的號碼牌(Session ID)犬缨。這樣喳魏,顧客(HTTP Request)下次來的時候,就又帶著號碼牌回來了怀薛。 我們可以看到刺彩,Session ID實際上是在客戶端和服務端之間通過HTTP Request和HTTP Response傳來傳去的。
二枝恋、一般用來實現(xiàn)Session的方法有兩種
URL重寫
Web Server在返回Response的時候创倔,檢查頁面中所有的URL,包括所有的連接焚碌,和HTML Form的Action屬性畦攘,在這些URL后面加上“;jsessionid=XXX”。 下一次十电,用戶訪問這個頁面中的URL知押。jsessionid就會傳回到Web Server。
Cookie
如果客戶端支持Cookie鹃骂,Web Server在返回Response的時候台盯,在Response的Header部分,加入一個“set-cookie: jsessionid=XXXX”header屬性畏线,把jsessionid放在Cookie里傳到客戶端静盅。
客戶端會把Cookie存放在本地文件里,下一次訪問Web Server的時候寝殴,再把Cookie的信息放到HTTP Request的“Cookie”header屬性里面蒿叠,這樣jsessionid就隨著HTTP Request返回給Web Server。
三蚣常、session的工作原理
1市咽、當一個用戶向服務器發(fā)送第一個請求時,服務器為其建立一個session史隆,并為此session創(chuàng)建一個標識號魂务;
2、這個用戶隨后的所有請求都應包括這個標識號泌射。服務器會校對這個標識號以判斷請求屬于哪個session。這種機制不使用IP作為標識鬓照,是因為很多機器是通過代理服務器方式上網(wǎng)熔酷,沒法區(qū)分每一臺機器。 對于session標識號(sessionID)豺裆,有兩種方式實現(xiàn):cookies和URL重寫拒秘。
四号显、HttpSession總結
1、HTTP協(xié)議本身是“連接-請求-應答-關閉連接”模式的躺酒,是一種無狀態(tài)協(xié)議(HTTP只是一個傳輸協(xié)議)押蚤;
2、Cookie規(guī)范是為了給HTTP增加狀態(tài)跟蹤用的(如果要精確把握羹应,建議仔細閱讀一下相關的RFC)揽碘,但不是唯一的手段;
3园匹、所謂Session雳刺,指的是客戶端和服務端之間的一段交互過程的狀態(tài)信息(數(shù)據(jù));這個狀態(tài)如何界定裸违,生命期有多長掖桦,這是應用本身的事情;
4供汛、 由于B/S計算模型中計算是在服務器端完成的枪汪,客戶端只有簡單的顯示邏輯,所以怔昨,Session數(shù)據(jù)對客戶端應該是透明的不可理解的并且應該受控于服 務端料饥;Session數(shù)據(jù)要么保存到服務端(HttpSession),要么在客戶端和服務端之間傳遞(Cookie或url rewritting或Hidden input)朱监;
5岸啡、由于HTTP本身的無狀態(tài)性,服務端無法知道客戶端相繼發(fā)來的請求是來自一個客戶的赫编,所以巡蘸,當使用服務端HttpSession存儲會話數(shù)據(jù)的時候客戶端的每個請求都應該包含一個session的標識(sid, jsessionid 等等)來告訴服務端;
6擂送、會話數(shù)據(jù)保存在服務端(如HttpSession)的好處是減少了HTTP請求的長度悦荒,提高了網(wǎng)絡傳輸效率;客戶端session信息存儲則相反嘹吨;
7搬味、 客戶端Session存儲只有一個辦法:cookie(url rewritting和hidden input因為無法做到持久化,不算蟀拷,只能作為交換session id的方式碰纬,即a method of session tracking),而服務端做法大致也是一個道理:容器有個session管理器(如tomcat的 org.apache.catalina.session包里面的類)问芬,提供session的生命周期和持久化管理并提供訪問session數(shù)據(jù)的 api悦析;
8、使用服務端還是客戶端session存儲要看應用的實際情況的此衅。一般來說不要求用戶注冊登錄的公共服務系統(tǒng)(如google)采用 cookie做客戶 端session存儲(如google的用戶偏好設置)强戴,而有用戶管理的系統(tǒng)則使用服務端存儲亭螟。原因很顯然:無需用戶登錄的系統(tǒng)唯一能夠標識用戶的就是用 戶的電腦,換一臺機器就不知道誰是誰了骑歹,服務端session存儲根本不管用预烙;而有用戶管理的系統(tǒng)則可以通過用戶id來管理用戶個人數(shù)據(jù),從而提供任意復 雜的個性化服務道媚;
9扁掸、客戶端和服務端的session存儲在性能、安全性衰琐、跨站能力也糊、編程方便性等方面都有一定的區(qū)別,而且優(yōu)劣并非絕對(譬如 TheServerSide 號稱不使用HttpSession羡宙,所以性能好狸剃,這很顯然:一個具有上億的訪問用戶的系統(tǒng),要在服務端數(shù)據(jù)庫中檢索出用戶的偏好信息顯然是低效 的狗热,Session管理器不管用什么數(shù)據(jù)結構和算法都要耗費大量內存和CPU時間钞馁;而用cookie,則根本不用檢索和維護session數(shù)據(jù)匿刮,服務器可 以做成無狀態(tài)的僧凰,當然高效);
10熟丸、 所謂的“會話cookie”簡單的說就是沒有明確指明有效期的cookie训措,僅在瀏覽器當前進程生命期內有效,可以被后繼的Set-Cookie操作清除掉光羞。
當 程序需要為某個客戶端的請求創(chuàng)建一個session的時候绩鸣,服務器首先檢查這個客戶端的請求里是否已包含了一個session標識 - 稱為 session id,如果已包含一個session id則說明以前已經為此客戶端創(chuàng)建過session纱兑,服務器就按照session id把這個 session檢索出來使用(如果檢索不到呀闻,可能會新建一個),如果客戶端請求不包含session id潜慎,則為此客戶端創(chuàng)建一個session并且生成一個與此session相關聯(lián)的session id捡多,session id的值應該是一個既不會重復,又不容易被找到規(guī)律以仿造的字符串铐炫,這個 session id將被在本次響應中返回給客戶端保存垒手。
保存這個session id的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動的按照規(guī)則把這個標識發(fā)揮給服務器驳遵。一般這個cookie的名字都是類似于SEEESIONID.
五淫奔、Session何時被創(chuàng)建、何時被刪除
何時創(chuàng)建:一 個常見的誤解是以為session在有客戶端訪問時就被創(chuàng)建堤结,然而事實是直到某server端程序調用 HttpServletRequest.getSession(true)這樣的語句時才被創(chuàng)建唆迁,注意如果JSP沒有顯示的使用 <% @page session="false"%> 關閉session,則JSP文件在編譯成Servlet時將會自動加上這樣一條語句 HttpSession session = HttpServletRequest.getSession(true);這也是JSP中隱含的 session對象的來歷竞穷。由于session會消耗內存資源唐责,因此,如果不打算使用session瘾带,應該在所有的JSP中關閉它鼠哥。
何時刪除:
a.程序調用HttpSession.invalidate();
b.距離上一次收到客戶端發(fā)送的session id時間間隔超過了session的超時設置;
c.服務器進程被停止(非持久session)
如何做到在瀏覽器關閉的時候刪除cookie?
嚴格的講看政,做不到這一點朴恳。可以做一點努力的辦法是在所有的客戶端頁面里使用javascript代碼window.oncolose來監(jiān)視瀏覽器的關閉動作允蚣,然后向服務器發(fā)送一個請求來刪除session于颖。但是對于瀏覽器崩潰或者強行殺死進程這些非常規(guī)手段仍然無能為力。
六嚷兔、Session的其他問題
1森渐、存放在session中的對象必須是可序列化的嗎?
不是必需的冒晰。要求對象可序列化只是為了session能夠在集群中被復制或者能夠持久保存或者在必要時server能夠暫時把session交換出內存同衣。
2、如何才能正確的應付客戶端禁止cookie的可能性
對所有的URL使用URL重寫壶运,包括超鏈接耐齐,form的action,和重定向的URL
3蒋情、開兩個瀏覽器窗口訪問應用程序會使用同一個session還是不同的session
七埠况、理解Cookie機制
1、cookie機制的基本原理就如上面的例子一樣簡單恕出,但是還有幾個問題需要解決:“會員卡”如何分發(fā)询枚;“會員卡”的內容;以及客戶如何使用“會員卡”浙巫。
2金蜀、正統(tǒng)的cookie分發(fā)是通過擴展HTTP協(xié)議來實現(xiàn)的,服務器通過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie的畴。然而純粹的客戶端腳本如JavaScript或者VBScript也可以生成cookie渊抄。
3、而cookie的使用是由瀏覽器按照一定的原則在后臺自動發(fā)送給服務器的丧裁。瀏覽器檢查所有存儲的cookie护桦,如果某個cookie所聲明的作用范圍大于 等于將要請求的資源所在的位置,則把該cookie附在請求資源的HTTP請求頭上發(fā)送給服務器煎娇。意思是麥當勞的會員卡只能在麥當勞的店里出示二庵,如果某家 分店還發(fā)行了自己的會員卡贪染,那么進這家店的時候除了要出示麥當勞的會員卡,還要出示這家店的會員卡催享。
八杭隙、cookie的內容
主要包括:名字,值因妙,過期時間痰憎,路徑和域。
路徑攀涵、域和作用范圍:其中域可以指定某一個域比如.google.com铣耘,相當于總店招牌,比如寶潔公司以故,也可以指定一個域下的具體某臺機器比如www.google.com或者froogle.google.com蜗细,可以用飄柔來做比。路徑就是跟在域名后面的URL路徑据德,比如/或者/foo等等鳄乏,可以用某飄柔專柜做比。路徑與域合在一起就構成了cookie的作用范圍棘利。
過期時間:如 果不設置過期時間橱野,則表示這個cookie的生命期為瀏覽器會話期間,只要關閉瀏覽器窗口善玫,cookie就消失了水援。這種生命期為瀏覽器會話期的 cookie被稱為會話cookie。會話cookie一般不存儲在硬盤上而是保存在內存里茅郎,當然這種行為并不是規(guī)范規(guī)定的蜗元。如果設置了過期時間,瀏覽器 就會把 cookie保存到硬盤上系冗,關閉后再次打開瀏覽器奕扣,這些cookie仍然有效直到超過設定的過期時間。
瀏覽器差異:存 儲在硬盤上的cookie可以在不同的瀏覽器進程間共享掌敬,比如兩個IE窗口惯豆。而對于保存在內存里的cookie,不同的瀏覽器有不同的處理方式奔害。對于 IE楷兽,在一個打開的窗口上按Ctrl-N(或者從文件菜單)打開的窗口可以與原窗口共享,而使用其他方式新開的IE進程則不能共享已經打開的窗口的內存 cookie华临;對于Mozilla Firefox0.8芯杀,所有的進程和標簽頁都可以共享同樣的cookie。一般來說是用javascript的window.open打開的窗口會與原窗 口共享內存cookie。瀏覽器對于會話cookie的這種只認cookie不認人的處理方式經常給采用session機制的web應用程序開發(fā)者造成很大的困擾揭厚。