在web應(yīng)用的開(kāi)發(fā)中我們會(huì)經(jīng)??吹竭@樣的url:http://www.xxx.com/xxx_app;jsessionid=xxxxxxxxxx?a=x&b=x...。這跟一般的url基本一樣,只有一個(gè)地方有區(qū)別,那就是“;jessionid=xxxxxxxx”。這個(gè)參數(shù)有時(shí)候有,有時(shí)候又沒(méi)有,說(shuō)它是參數(shù)可又跟一般傳遞的參數(shù)不同,它是緊跟在url后面用分號(hào)來(lái)分隔的,用一般的request.getParameter()方法還取不到。那這個(gè)參數(shù)到底是干嘛用的呢?要了解它還要先了解session的實(shí)現(xiàn)方式。
session的實(shí)現(xiàn)方式
做web開(kāi)發(fā)的同學(xué)都知道,http是無(wú)狀態(tài)的會(huì)話(huà)協(xié)議,也就是說(shuō)無(wú)法保存用戶(hù)的信息。那如果有一些信息需要在用戶(hù)的瀏覽活動(dòng)中一直保持,該怎么做呢?我們可以把這些信息在每次請(qǐng)求的時(shí)候作為參數(shù)傳遞給服務(wù)器,但這樣做既麻煩又耗費(fèi)資源,這時(shí)候就體現(xiàn)出了session的重要性。session是web開(kāi)發(fā)中不可或缺的一個(gè)特性。它是對(duì)于一個(gè)特定的用戶(hù)請(qǐng)求,在web服務(wù)器上保存的一個(gè)全局變量。有了它我們就可以把用戶(hù)的一些信息保存在服務(wù)器上,而不用在服務(wù)器和客戶(hù)端之間來(lái)回傳遞。知道了session的作用,那session是怎么實(shí)現(xiàn)的呢?服務(wù)器上為每個(gè)用戶(hù)都保存了一個(gè)session,那當(dāng)用戶(hù)請(qǐng)求過(guò)來(lái)的時(shí)候是怎么知道某一個(gè)用戶(hù)應(yīng)該對(duì)應(yīng)哪個(gè)session呢?這時(shí)jsessionid就派上用場(chǎng)了。每一個(gè)session都有一個(gè)id來(lái)作為標(biāo)識(shí),這個(gè)id會(huì)傳到客戶(hù)端,每次客戶(hù)端請(qǐng)求都會(huì)把這個(gè)id傳到服務(wù)器,服務(wù)器根據(jù)id來(lái)匹配這次請(qǐng)求應(yīng)該使用哪個(gè)session。jsessionid就是客戶(hù)端用來(lái)保存sessionid的變量,主要是針對(duì)j2ee實(shí)現(xiàn)的web容器,沒(méi)有研究過(guò)其他語(yǔ)言是用什么變量來(lái)保存的。一般對(duì)于web應(yīng)用來(lái)說(shuō),客戶(hù)端變量都會(huì)保存在cookie中,jsessionid也不例外。不過(guò)與一般的cookie變量不同,jsessionid是保存在內(nèi)存cookie中的,在一般的cookie文件中是看不到它的影子的。內(nèi)存cookie在打開(kāi)一個(gè)瀏覽器窗口的時(shí)候會(huì)創(chuàng)建,在關(guān)閉這個(gè)瀏覽器窗口的時(shí)候也同時(shí)銷(xiāo)毀。這也就解釋了為什么session變量不能跨窗口使用,要跨窗口使用就需要手動(dòng)把jsessionid保存到cookie里面。
jsessionid的作用
在以上的文字中我們了解了session的實(shí)現(xiàn)原理,同時(shí)也知道了session跟jsessionid緊密不可分割的聯(lián)系。只有通過(guò)jsessionid才能使session機(jī)制起作用,而jsessionid又是通過(guò)cookie來(lái)保存??吹竭@里,也許你會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題,如果用戶(hù)禁用了cookie,那jsessionid不是就不能保存了嗎?session不是不起作用了嗎?我們真的對(duì)此束手無(wú)策了嗎?當(dāng)然不是。在用戶(hù)禁用了cookie時(shí)候,我們可以通過(guò)url重寫(xiě)來(lái)實(shí)現(xiàn)jsessionid的傳遞。這就是我上面指出的那樣的url:http://www.xxx.com/xxx_app;jsessionid=xxxxxxxxxx?a=x&b=x..。jessionid通過(guò)這樣的方式來(lái)從客戶(hù)端傳遞到服務(wù)器端,從而來(lái)標(biāo)識(shí)session。注意一點(diǎn),jsessionid跟一般的url參數(shù)傳遞方式是不同的,不是作為參數(shù)跟在?后面,而是緊跟在url后面用;來(lái)分隔。這樣在用戶(hù)禁用cookie的時(shí)候我們也可以傳遞jsessionid來(lái)使用session了,只不過(guò)需要每次都把jseesionid作為參數(shù)跟在url后面?zhèn)鬟f。那這樣豈不是很麻煩,每次請(qǐng)求一個(gè)url都要判斷cookie是否可用,如果禁用了cookie,還要從url里解析出jsessionid,然后跟在處理完后轉(zhuǎn)到的url后面,以保持jsessionid的傳遞。這些問(wèn)題sun當(dāng)然已經(jīng)幫我們想到了,所以提供了2個(gè)方法來(lái)使事情變得簡(jiǎn)單:response.encodeURL()和response.encodeRedirectURL()。這2個(gè)方法會(huì)判斷cookie是否可用,如果禁用了會(huì)解析出url中的jsessionid,并連接到指定的url后面,如果沒(méi)有找到j(luò)essionid會(huì)自動(dòng)幫我們生成一個(gè)。至于為什么要有2個(gè)方法?這2個(gè)方法有什么不同?google了一下,說(shuō)是這2個(gè)方法在判斷是否要包含jsessionid的邏輯上會(huì)稍有不同。在調(diào)用HttpServletResponse.sendRedirect前,應(yīng)該先調(diào)用encodeRedirectURL()方法,否則可能會(huì)丟失Sesssion信息。這2個(gè)方法的使用方法如:response.sendRedirect(response.encodeURL("/myapp/input.jsp"));。如果cookie沒(méi)有禁用,我們?cè)跒g覽器地址欄中看到的地址是這樣的:/myapp/input.jsp,如果禁用了cookie,我們會(huì)看到:/myapp/input.jsp;jsessionid=73E6B2470C91A433A6698C7681FD44F4。所以,我們?cè)趯?xiě)web應(yīng)用的時(shí)候,為了保險(xiǎn)起見(jiàn),應(yīng)該在程序里的每一個(gè)跳轉(zhuǎn)url上都使用這2個(gè)方法,來(lái)保證session的可用性。
說(shuō)道這里,大家應(yīng)該對(duì)jsessionid和session的關(guān)系,以及jsessionid的作用有個(gè)了一個(gè)大致的了解,具體應(yīng)用還要自己在項(xiàng)目中具體情況具體對(duì)待。
聯(lián)系客服