session在web開(kāi)發(fā)中是一個(gè)非常重要的概念枢泰,這個(gè)概念很抽象,很難定義铡溪,也是最讓人迷惑的一個(gè)名詞漂辐,也是最多被濫用的名字之一,在不同的場(chǎng)合棕硫,session一次的含義也很不相同髓涯。這里只探討HTTP Session。
為了說(shuō)明問(wèn)題饲帅,這里基于Java Servlet理解Session的概念與原理复凳,這里所說(shuō)Servlet已經(jīng)涵蓋了JSP技術(shù),因?yàn)镴SP最終也會(huì)被編譯為Servlet灶泵,兩者有著相同的本質(zhì)育八。
在Java中,HTTP的Session對(duì)象用javax.servlet.http.HttpSession來(lái)表示赦邻。
1髓棋、概念:Session代表服務(wù)器與瀏覽器的一次會(huì)話過(guò)程,這個(gè)過(guò)程是連續(xù)的,也可以時(shí)斷時(shí)續(xù)的按声。在Servlet中膳犹,session指的是HttpSession類的對(duì)象,這個(gè)概念到此結(jié)束了签则,也許會(huì)很模糊须床,但只有看完本文,才能真正有個(gè)深刻理解渐裂。
2豺旬、Session創(chuàng)建的時(shí)間是:
一個(gè)常見(jiàn)的誤解是以為session在有客戶端訪問(wèn)時(shí)就被創(chuàng)建,然而事實(shí)是直到某server端程序調(diào)用 HttpServletRequest.getSession(true)這樣的語(yǔ)句時(shí)才被創(chuàng)建柒凉,注意如果JSP沒(méi)有顯示的使用 <% @page session="false"%> 關(guān)閉session族阅,則JSP文件在編譯成Servlet時(shí)將會(huì)自動(dòng)加上這樣一條語(yǔ)句 HttpSession session = HttpServletRequest.getSession(true);這也是JSP中隱含的 session對(duì)象的來(lái)歷。
由于session會(huì)消耗內(nèi)存資源膝捞,因此坦刀,如果不打算使用session,應(yīng)該在所有的JSP中關(guān)閉它蔬咬。
引申:
1)鲤遥、訪問(wèn)*.html的靜態(tài)資源因?yàn)椴粫?huì)被編譯為Servlet,也就不涉及session的問(wèn)題计盒。
2)渴频、當(dāng)JSP頁(yè)面沒(méi)有顯式禁止session的時(shí)候,在打開(kāi)瀏覽器第一次請(qǐng)求該jsp的時(shí)候,服務(wù)器會(huì)自動(dòng)為其創(chuàng)建一個(gè)session膘盖,并賦予其一個(gè)sessionID托酸,發(fā)送給客戶端的瀏覽器。以后客戶端接著請(qǐng)求本應(yīng)用中其他資源的時(shí)候发笔,會(huì)自動(dòng)在請(qǐng)求頭上添加:
Cookie:JSESSIONID=客戶端第一次拿到的session ID
這樣,服務(wù)器端在接到請(qǐng)求時(shí)候,就會(huì)收到session ID懈涛,并根據(jù)ID在內(nèi)存中找到之前創(chuàng)建的session對(duì)象,提供給請(qǐng)求使用泳猬。這也是session使用的基本原理----搞不懂這個(gè)批钠,就永遠(yuǎn)不明白session的原理。
下面是兩次請(qǐng)求同一個(gè)jsp得封,請(qǐng)求頭信息:
通過(guò)圖可以清晰發(fā)現(xiàn)埋心,第二次請(qǐng)求的時(shí)候,已經(jīng)添加session ID的信息忙上。
3拷呆、Session刪除的時(shí)間是:
1)Session超時(shí):超時(shí)指的是連續(xù)一定時(shí)間服務(wù)器沒(méi)有收到該Session所對(duì)應(yīng)客戶端的請(qǐng)求,并且這個(gè)時(shí)間超過(guò)了服務(wù)器設(shè)置的Session超時(shí)的最大時(shí)間。
2)程序調(diào)用HttpSession.invalidate()
3)服務(wù)器關(guān)閉或服務(wù)停止
4茬斧、session存放在哪里:服務(wù)器端的內(nèi)存中腰懂。不過(guò)session可以通過(guò)特殊的方式做持久化管理。
5项秉、session的id是從哪里來(lái)的绣溜,sessionID是如何使用的:當(dāng)客戶端第一次請(qǐng)求session對(duì)象時(shí)候,服務(wù)器會(huì)為客戶端創(chuàng)建一個(gè)session娄蔼,并將通過(guò)特殊算法算出一個(gè)session的ID涮毫,用來(lái)標(biāo)識(shí)該session對(duì)象,當(dāng)瀏覽器下次(session繼續(xù)有效時(shí))請(qǐng)求別的資源的時(shí)候贷屎,瀏覽器會(huì)偷偷地將sessionID放置到請(qǐng)求頭中罢防,服務(wù)器接收到請(qǐng)求后就得到該請(qǐng)求的sessionID,服務(wù)器找到該id的session返還給請(qǐng)求者(Servlet)使用唉侄。一個(gè)會(huì)話只能有一個(gè)session對(duì)象咒吐,對(duì)session來(lái)說(shuō)是只認(rèn)id不認(rèn)人。
6属划、session會(huì)因?yàn)闉g覽器的關(guān)閉而刪除嗎恬叹?
不會(huì),session只會(huì)通過(guò)上面提到的方式去關(guān)閉同眯。
7绽昼、同一客戶端機(jī)器多次請(qǐng)求同一個(gè)資源,session一樣嗎须蜗?
一般來(lái)說(shuō)硅确,每次請(qǐng)求都會(huì)新創(chuàng)建一個(gè)session。
其實(shí)明肮,這個(gè)也不一定的菱农,總結(jié)下:對(duì)于多標(biāo)簽的瀏覽器(比如360瀏覽器)來(lái)說(shuō),在一個(gè)瀏覽器窗口中柿估,多個(gè)標(biāo)簽同時(shí)訪問(wèn)一個(gè)頁(yè)面循未,session是一個(gè)。對(duì)于多個(gè)瀏覽器窗口之間秫舌,同時(shí)或者相隔很短時(shí)間訪問(wèn)一個(gè)頁(yè)面的妖,session是多個(gè)的,和瀏覽器的進(jìn)程有關(guān)足陨。對(duì)于一個(gè)同一個(gè)瀏覽器窗口嫂粟,直接錄入url訪問(wèn)同一應(yīng)用的不同資源,session是一樣的钠右。
8赋元、session是一個(gè)容器,可以存放會(huì)話過(guò)程中的任何對(duì)象。
9搁凸、session因?yàn)檎?qǐng)求(request對(duì)象)而產(chǎn)生媚值,同一個(gè)會(huì)話中多個(gè)request共享了一session對(duì)象,可以直接從請(qǐng)求中獲取到session對(duì)象护糖。
10褥芒、其實(shí),session的創(chuàng)建和使用總在服務(wù)端嫡良,而瀏覽器從來(lái)都沒(méi)得到過(guò)session對(duì)象锰扶。但瀏覽器可以請(qǐng)求Servlet(jsp也是Servlet)來(lái)獲取session的信息∏奘埽客戶端瀏覽器真正緊緊拿到的是session ID坷牛,而這個(gè)對(duì)于瀏覽器操作的人來(lái)說(shuō),是不可見(jiàn)的很澄,并且用戶也無(wú)需關(guān)心自己處于哪個(gè)會(huì)話過(guò)程中京闰。
本文出自 “熔 巖” 博客,請(qǐng)務(wù)必保留此出處http://lavasoft.blog.51cto.com/62575/275589