日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jsessionid

發(fā)布時(shí)間:2024/1/23 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jsessionid 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在服務(wù)器端,我們用慣了session.setAttribute("",userInfo)這樣的一行代碼,估計(jì)你很少想到:服務(wù)器與瀏覽器之間是如何保持會(huì)話狀態(tài)的。好了,先引用一些文章的精彩片段:http://www.xxx.com/xxx_app;jsessionid=xxxxxxxxxx?a=x&b=x。

這跟一般的url基本一樣,只有一個(gè)地方有區(qū)別,那就是“;jessionid=xxxxxxxx”。這個(gè)參數(shù)有時(shí)候有,有時(shí)候又沒有,說它是參數(shù)可又跟一般傳遞的參數(shù)不同,它是緊跟在url后面用分號(hào)來分隔的 ,用一般的request.getParameter()方法還取不到j(luò)sessionid 。

?session的實(shí)現(xiàn)方式

做web開發(fā)的同學(xué)都知道,http是無狀態(tài)的會(huì)話協(xié)議,也就是說無法保存用戶的信息。那如果有一些信息需要在用戶的瀏覽活動(dòng)中一直保持,該怎么做呢?我們可以把這些信息在每次請(qǐng)求的時(shí)候作為參數(shù)傳遞給服務(wù)器,但這樣做既麻煩又耗費(fèi)資源,這時(shí)候就體現(xiàn)出了session的重要性。session是web開發(fā)中不可或缺的一個(gè)特性。它是對(duì)于一個(gè)特定的用戶請(qǐng)求,在web服務(wù)器上保存的一個(gè)全局變量。有了它我們就可以把用戶的一些信息保存在服務(wù)器上,而不用在服務(wù)器和客戶端之間來回傳遞。知道了session的作用,那session是怎么實(shí)現(xiàn)的呢?服務(wù)器上為每個(gè)用戶都保存了一個(gè)session,那當(dāng)用戶請(qǐng)求過來的時(shí)候是怎么知道某一個(gè)用戶應(yīng)該對(duì)應(yīng)哪個(gè)session呢?這時(shí)jsessionid就派上用場了。每一個(gè)session都有一個(gè)id來作為標(biāo)識(shí),這個(gè)id會(huì)傳到客戶端,每次客戶端請(qǐng)求都會(huì)把這個(gè)id傳到服務(wù)器,服務(wù)器根據(jù)id來匹配這次請(qǐng)求應(yīng)該使用哪個(gè)session。jsessionid就是客戶端用來保存sessionid的變量,主要是針對(duì)j2ee實(shí)現(xiàn)的web容器,沒有研究過其他語言是用什么變量來保存的。一般對(duì)于web應(yīng)用來說,客戶端變量都會(huì)保存在cookie中,jsessionid也不例外。不過與一般的cookie變量不同,jsessionid是保存在內(nèi)存cookie中的,在一般的cookie文件中是看不到它的影子的。內(nèi)存cookie在打開一個(gè)瀏覽器窗口的時(shí)候會(huì)創(chuàng)建,在關(guān)閉這個(gè)瀏覽器窗口的時(shí)候也同時(shí)銷毀。這也就解釋了為什么session變量不能跨窗口使用,要跨窗口使用就需要手動(dòng)把jsessionid保存到cookie里面。

jsessionid的作用

在以上的文字中我們了解了session的實(shí)現(xiàn)原理,同時(shí)也知道了session跟jsessionid緊密不可分割的聯(lián)系。只有通過jsessionid才能使session機(jī)制起作用,而jsessionid又是通過cookie來保存。看到這里,也許你會(huì)發(fā)現(xiàn)一個(gè)問題,如果用戶禁用了cookie,那jsessionid不是就不能保存了嗎?session不是不起作用了嗎?我們真的對(duì)此束手無策了嗎?當(dāng)然不是。在用戶禁用了cookie時(shí)候,我們可以通過url重寫來實(shí)現(xiàn)jsessionid的傳遞。這就是我上面指出的那樣的url:http://www.xxx.com/xxx_app;jsessionid=xxxxxxxxxx?a=x&b=x..。jessionid通過這樣的方式來從客戶端傳遞到服務(wù)器端,從而來標(biāo)識(shí)session。注意一點(diǎn),jsessionid跟一般的url參數(shù)傳遞方式是不同的,不是作為參數(shù)跟在?后面,而是緊跟在url后面用;來分隔。這樣在用戶禁用cookie的時(shí)候我們也可以傳遞jsessionid來使用session了,只不過需要每次都把jseesionid作為參數(shù)跟在url后面?zhèn)鬟f。那這樣豈不是很麻煩,每次請(qǐng)求一個(gè)url都要判斷cookie是否可用,如果禁用了cookie,還要從url里解析出jsessionid,然后跟在處理完后轉(zhuǎn)到的url后面,以保持jsessionid的傳遞。這些問題sun當(dāng)然已經(jīng)幫我們想到了,所以提供了2個(gè)方法來使事情變得簡單:response.encodeURL()和response.encodeRedirectURL()。這2個(gè)方法會(huì)判斷cookie是否可用,如果禁用了會(huì)解析出url中的jsessionid,并連接到指定的url后面,如果沒有找到j(luò)essionid會(huì)自動(dòng)幫我們生成一個(gè)。至于為什么要有2個(gè)方法?這2個(gè)方法有什么不同?google了一下,說是這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沒有禁用,我們?cè)跒g覽器地址欄中看到的地址是這樣的:/myapp/input.jsp,如果禁用了cookie,我們會(huì)看到:/myapp/input.jsp;jsessionid=73E6B2470C91A433A6698C7681FD44F4。所以,我們?cè)趯憌eb應(yīng)用的時(shí)候,為了保險(xiǎn)起見,應(yīng)該在程序里的每一個(gè)跳轉(zhuǎn)url上都使用這2個(gè)方法,來保證session的可用性。

?

啟動(dòng)你的tomcat,打開FireFox(愛得不得了,一定要安裝FireBug),輸入localhost就行,打開firebug,點(diǎn)網(wǎng)絡(luò),你會(huì)看到,瀏覽器與服務(wù)器會(huì)話的信息,給出瀏覽器

(1)第一次請(qǐng)求服務(wù)器:

瀏覽器的請(qǐng)求頭信息

Hostlocalhost
User-AgentMozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
Accepttext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Languagezh-cn,zh;q=0.5
Accept-Encodinggzip,deflate
Accept-CharsetGB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive115
Connection

keep-alive

?

服務(wù)器響應(yīng)頭信息

ServerApache-Coyote/1.1
Set-CookieJSESSIONID=64D21B4D69DFB3041B6375C1932BD6CB; Path=/
Content-Typetext/html;charset=UTF-8
Content-Languagezh-CN
Content-Length242
DateMon, 28 Jun 2010 02:35:29 GMT

(2)第二次請(qǐng)求服務(wù)器:

瀏覽器的請(qǐng)求頭信息

Hostlocalhost
User-AgentMozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
Accepttext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Languagezh-cn,zh;q=0.5
Accept-Encodinggzip,deflate
Accept-CharsetGB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive115
Connectionkeep-alive
CookieJSESSIONID=64D21B4D69DFB3041B6375C1932BD6CB

服務(wù)器響應(yīng)頭信息

ServerApache-Coyote/1.1
Content-Typetext/html;charset=UTF-8
Content-Languagezh-CN
Content-Length242
DateMon, 28 Jun 2010 02:37:51 GMT

重復(fù)第三次,每四次...第N次請(qǐng)求服務(wù)器,瀏覽器和服務(wù)器的請(qǐng)求頭信息都是與第二次請(qǐng)求服務(wù)器是一樣的。

?

(3)但是,如果你在服務(wù)器端加入如下一行代碼:

Log.info("SessionId:" + request.getSession().getId());

你會(huì)看到,當(dāng)你第一次請(qǐng)求服務(wù)器時(shí),就會(huì)默認(rèn)有一個(gè)新的session被創(chuàng)建,而且在session的有效時(shí)間范圍內(nèi),這個(gè)輸出值是不會(huì)變的,否則,服務(wù)器會(huì)重新創(chuàng)建一個(gè)session,自然,sessionId也就不同了,這段代碼的輸出自然也會(huì)不同了。

?

(4)你必須注意這一點(diǎn):你用的是瀏覽器與服務(wù)器通信:

有一些事情是瀏覽器幫助我們?nèi)プ隽?#xff0c;那就是:當(dāng)你第一次與服務(wù)器通信時(shí),瀏覽器會(huì)保存服務(wù)器返回的 Set-Cookie 這個(gè)健的值( JSESSIONID=64D21B4D69DFB3041B6375C1932BD6CB ),只要你不關(guān)閉瀏覽器(徹底關(guān)閉,關(guān)閉選項(xiàng)卡不算),瀏覽器會(huì)從第二次向服務(wù)器發(fā)出請(qǐng)求開始,一直帶上這個(gè)鍵值對(duì),發(fā)給服務(wù)器。服務(wù)器就會(huì)知道,這是同一個(gè)人(同一個(gè)會(huì)話)發(fā)起的請(qǐng)求。

?

(5)我們?cè)僮⒁庖幌?#xff1a;request.setAttribute("sysuser",userInfo)這句話:

當(dāng)你第一次請(qǐng)求服務(wù)器時(shí),這句代碼會(huì)根據(jù)服務(wù)器默認(rèn)產(chǎn)生的session得到ID,并與sysuser=userInfo這個(gè)鍵值對(duì)掛上鉤(當(dāng)然,userInfo可以是任何對(duì)象),保證唯一關(guān)聯(lián),檢測用戶是否登錄就是這樣實(shí)現(xiàn)的。

我一定要聲明一點(diǎn):保持一個(gè)會(huì)話與用戶是否登錄是沒有任何關(guān)系的。

?

(6)再次引深一下,如果你用的不是瀏覽器,比如說做J2ME開發(fā),怎樣保持會(huì)話呢?

(1) 在你寫完這行代碼后:HttpConnection hc = (HttpConnection)Connector.open(httpURL),加入以下代碼:( Constant.sessionID只是一個(gè)靜態(tài)變量 )

?

view plaincopy to clipboardprint?

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

  • //在與服務(wù)器通信前設(shè)置sessionId,維持唯一的一個(gè)會(huì)話 ??
  • if?(Constant.sessionID?!=?null)?{??
  • ???hc.setRequestProperty("Cookie",?AppContext.CurrentAppContext.sessionID);??
  • }??
  • [java] view plaincopyprint?

  • //在與服務(wù)器通信前設(shè)置sessionId,維持唯一的一個(gè)會(huì)話if?(Constant.sessionID?!=?null)?{???hc.setRequestProperty("Cookie",?AppContext.CurrentAppContext.sessionID);}??
  • //在與服務(wù)器通信前設(shè)置sessionId,維持唯一的一個(gè)會(huì)話if (Constant.sessionID != null) { hc.setRequestProperty("Cookie", AppContext.CurrentAppContext.sessionID);}

    ?

    ?

    (2) A:只向服務(wù)器讀數(shù)據(jù),不向服務(wù)寫數(shù)據(jù),B:先向服務(wù)器寫數(shù)據(jù),再從服務(wù)器讀數(shù)據(jù)

    對(duì)于這兩種情況,只要你第一次打開openDataInputStream(),這可以加入以下代碼( Constant.isLogin 只是一個(gè)靜態(tài)變量boolean ):

    ?

    view plaincopy to clipboardprint?

    ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

  • //每次與服務(wù)器通信后,保存?sessionId ??
  • String?cookie?=?hc.getHeaderField("Set-Cookie");??
  • if?(cookie?!=?null)?{??
  • ??????String?jsessionId?=?cookie.substring(0,cookie.indexOf(";"));??
  • ??????if(Constant.sessionID?!=?null?&&?!Constant.sessionID.equals(jsessionId)?&&?Constant.isLogin?){??
  • ??????????Log.info("sessionid超時(shí),?will?get?new?sessionid,?but?you?must?login?again");??
  • ??????????//設(shè)置為未登錄狀態(tài) ??
  • ??????????Constant.isLogin?=?false;??
  • ??????}??
  • ??????Constant.sessionID?=?jsessionId;??
  • }???
  • [java] view plaincopyprint?

  • //每次與服務(wù)器通信后,保存?sessionIdString?cookie?=?hc.getHeaderField("Set-Cookie");if?(cookie?!=?null)?{??????String?jsessionId?=?cookie.substring(0,cookie.indexOf(";"));??????if(Constant.sessionID?!=?null?&&?!Constant.sessionID.equals(jsessionId)?&&?Constant.isLogin?){??????????Log.info("sessionid超時(shí),?will?get?new?sessionid,?but?you?must?login?again");??????????//設(shè)置為未登錄狀態(tài)??????????Constant.isLogin?=?false;??????}??????Constant.sessionID?=?jsessionId;}???
  • //每次與服務(wù)器通信后,保存 sessionIdString cookie = hc.getHeaderField("Set-Cookie");if (cookie != null) { String jsessionId = cookie.substring(0,cookie.indexOf(";")); if(Constant.sessionID != null && !Constant.sessionID.equals(jsessionId) && Constant.isLogin ){ Log.info("sessionid超時(shí), will get new sessionid, but you must login again"); //設(shè)置為未登錄狀態(tài) Constant.isLogin = false; } Constant.sessionID = jsessionId;}?

    ?

    這樣就可以保持一個(gè)會(huì)話了。

    ?

    (7)最后,關(guān)于URL重定向

    引用一段話:sun幫我們想到了,所以提供了2個(gè)方法來使事情變得簡單:response.encodeURL()和response.encodeRedirectURL()。這2個(gè)方法會(huì)判斷cookie是否可用,如果禁用了會(huì)解析出url中的jsessionid,并連接到指定的url后面,如果沒有找到j(luò)essionid會(huì)自動(dòng)幫我們生成一個(gè)。至于為什么要有2個(gè)方法?這2個(gè)方法有什么不同?google了一下,說是這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沒有禁用,我們?cè)跒g覽器地址欄中看到的地址是這樣的:/myapp/input.jsp,如果禁用了 cookie,我們會(huì)看到:/myapp /input.jsp;jsessionid=73E6B2470C91A433A6698C7681FD44F4。所以,我們?cè)趯憌eb應(yīng)用的時(shí)候,為了保險(xiǎn)起見,應(yīng)該在程序里的每一個(gè)跳轉(zhuǎn)url上都使用這2個(gè)方法,來保證session的可用性。

    總結(jié)

    以上是生活随笔為你收集整理的jsessionid的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。