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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 重写session_关于session的实现:cookie与url重写

發布時間:2024/7/5 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 重写session_关于session的实现:cookie与url重写 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文討論的語境是java EE servlet。

我們都知道session的實現主要兩種方式:cookie與url重寫,而cookie是首選(默認)的方式,因為各種現代瀏覽器都默認開通cookie功能,但是每種瀏覽器也都有允許cookie失效的設置。

由于瀏覽器默認啟動cookie功能,而且普通客戶一般都不會取消cookie功能。久而久之,我們寫代碼的時候,也就不會在意session的具體實現,其實這里面還是有很多值得注意的地方,尤其在用戶取消cookie功能的情況下。

一 servlet session實現與接口簡要介紹:

servlet規范規定實現session的cookie名稱強制為jsessionid(在servlet 3.0 可以自定義了),在瀏覽器第一次請求的時候,服務器產生一個唯一的id,并把這個id設置給一個名為jsessionid的cookie,然后再通過reponse的addcookie,輸出到瀏覽器端。其實這些東西我們都可以通過debug模式下的去查看服務器,來驗證這些內容;或者用http協議攔截器來查看,因為servlet的所有接口也都是基于http協議的,

下面基于http協議解釋一下:

瀏覽器第一次請求:

GET /cxt/index.do HTTP/1.1

...

由于是第一次請求,所以沒有cookie要推給服務器

服務器返回:

HTTP/1.1 200 OK

Set-Cookie: JSESSIONID=3EF0AEC40F2C6C30A0580844C0E6B2E8; Path=/cxt

...

...

...

由于服務器沒發現瀏覽器沒提供任何cookie,服務器不知道是瀏覽器未提供cookie的原因:可能是cookie功能取消了,也可能是第一次訪問。所以服務器生成一個名為jsessionid的cookie,用Set-Cookie來把cookie推給瀏覽器;并且,服務器的servlet在生成html頁面的時候需要用reponse.encodeURL方法來編碼url,該方法其實就是用來實現url重寫功能的,這是因為瀏覽器可能是因為取消cookie功能,而未提供cookie的。服務器為了確保下次提交成功,必須確保生成給瀏覽器端的url帶有jsessionid。

若cookie功能沒取消,則瀏覽器瀏覽器第二次請求:

POST /cxt/login.do;jsessionid=3EF0AEC40F2C6C30A0580844C0E6B2E8 HTTP/1.1

Cookie: JSESSIONID=3EF0AEC40F2C6C30A0580844C0E6B2E8;

...

瀏覽器的下一次請求的時候用http的Cookie屬性把當前domain的Cookie都推給服務器,來表明自己的身份。這次,服務器知道瀏覽器支持cookie功能,servlet不需要再使用reponse.encodeURL來編碼url了

若瀏覽器cookie功能取消,則瀏覽器請求內容為

POST /cxt/login.do?jsessionid=3EF0AEC40F2C6C30A0580844C0E6B2E8 HTTP/1.1

...

服務器在接受到上述內容是,通過url后面的jsessionid參數知道這個請求與上一次請求是同一個session

與session有關的類接口:

HttpServletRequest.getSession

HttpSession

HttpServletResponse.encodeURL

二 實現url重寫的編碼注意點

1.既然瀏覽器可能被取消cookie功能,那么我們輸出給客戶端的代碼中必須要支持url重寫功能,分幾種情況解釋

假如純粹用jsp/servlet來寫,那么我們必須手動用reponse.encodeURL來編碼每一個url,包括的href,form的action,或者其他href

2.使用其它web框架的話,最好消息使用框架提供的輸出href功能,否則會有匪夷所思的結果。

比如用struts,若struts單獨提供了一個tag來實現html:rewrite,比如,在沒有jsessionid cookie的情況下,最后會生成http://localhost:8080/ctx/logout.do;jsessionid=0916FB057C169069;若有jsessionid cookie,則會生成http://localhost:8080/ctx/logout.do。但是我們還注意到html:rewrite還有一個href屬性,假如我們用href屬性的話,則struts不會生成帶有jsessionid參數。

struts中提供url重寫的功能的還有html:link與html:form,比如,這個tag功能與html:rewrite相似,也有href屬性,生成帶有標簽的html內容。,html:form沒有href屬性,只有action屬性。

3.假若沒有使用任何框架,則可以使用jstl提供的url重寫功能

jstl提供了標簽來實現c:url,比如,這個也會根據瀏覽器是否支持cookie,來生成帶有jsessionid屬性的url。

相信通過上面的總結,是我們對怎么使用session與cookie有更深入的認識。記住,在用jsp/servlet實現系統的時候,盡量不要自己寫標簽,最好使用系統框架自帶的標簽來實現,否則瀏覽器取消cookie功能的話,系統不支持url重寫功能。

使用表單隱藏域跟蹤Session重寫URL跟蹤Session

Servlet容器先在客戶端瀏覽器中保存一個Sessin ID,以后在瀏覽器發出的HTTP請求中就會包含這個Session ID,Servlet容器讀取HTTP請求中的Session ID,就能判斷出來自各個瀏覽器進程的HTTP請求屬于哪個會話。這一過程稱為Session跟蹤。如果瀏覽器支持Cookie,Servlet容器就把Session ID作為Cookie保存在瀏覽器中。

如果瀏覽器出于安全的原因,禁用Cookie,不允許服務器像客戶端存放Cookie。Servlet容器可以重寫Web組件的URL,把Session ID添加到URL信息中。

HttpServletResponse接口提供了重寫URL的方法:

public?String?encodeURL(String?url)

public?String?encodeRedirectURL(String?url)

只有在當前Web組件支持Session,并且瀏覽器不支持Cookie的情況下,encodeURL方法才會重寫URL,否則直接返回參數指定的原始URL。

例如:

encodeurl.jsp中包含如下代碼:

"/>

當瀏覽器請求訪問 encodeurl.jsp 文件時,如果當前JSP頁面支持Session,并且瀏覽器不支持Cookie,則上面的鏈接被解析為如下形式:

TOMCAT判斷客戶端瀏覽器是否支持Cookie的依據是請求中是否含有Cookie。盡管客戶端可能會支持Cookie,但是由于第一次請求時不會攜帶任何Cookie(因為并無任何Cookie可以攜帶),URL地址重寫后的地址中仍然會帶有jsessionid。當第二次訪問時服務器已經在瀏覽器中寫入Cookie了,因此URL地址重寫后的地址中就不會帶有jsessionid了。

在Session中禁用Cookie

既然可能客戶瀏覽器不支持Cookie,索性禁止Session使用Cookie,統一使用URL地址重寫會更好一些。

Java Web規范支持通過配置的方式禁用Cookie。

下面舉例說一下怎樣通過配置禁止使用Cookie。

打開項目sessionWeb的WebRoot目錄下的META-INF文件夾(跟WEB-INF文件夾同級,如果沒有則創建),打開context.xml(如果沒有則創建),編輯內容如下:

/META-INF/context.xml

或者修改Tomcat全局的conf/context.xml,修改內容如下:

//context.xml

部署后TOMCAT便不會自動生成名JSESSIONID的Cookie,Session也不會以Cookie為識別標志,而僅僅以重寫后的URL地址為識別標志了。

注意:該配置只是禁止Session使用Cookie作為識別標志,并不能阻止其他的Cookie讀寫。也就是說服務器不會自動維護名為JSESSIONID的Cookie了,但是程序中仍然可以讀寫其他的Cookie。

會話狀態保持,JSESSIONID,COOKIE之間的關系

在服務器端,我們用慣了session.setAttribute("",userInfo)這樣的一行代碼,估計你很少想到:服務器與瀏覽器之間是如何保持會話狀態的。好了,先引用一些文章的精彩片段:

http://www.xxx.com/xxx_app;jsessionid=xxxxxxxxxx?a=x&b=x。

這跟一般的url基本一樣,只有一個地方有區別,那就是“;jessionid=xxxxxxxx”。這個參數有時候有,有時候又沒有,說它是參數可又跟一般傳遞的參數不同,它是緊跟在url后面用分號來分隔的,用一般的request.getParameter()方法還取不到jsessionid。

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

(1)第一次請求服務器:

瀏覽器的請求頭信息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

服務器響應頭信息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)第二次請求服務器:

瀏覽器的請求頭信息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

服務器響應頭信息ServerApache-Coyote/1.1

Content-Typetext/html;charset=UTF-8

Content-Languagezh-CN

Content-Length242

DateMon, 28 Jun 2010 02:37:51

GMT

重復第三次,每四次...第N次請求服務器,瀏覽器和服務器的請求頭信息都是與第二次請求服務器是一樣的。

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

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

你會看到,當你第一次請求服務器時,就會默認有一個新的session被創建,而且在session的有效時間范圍內,這個輸出值是不會變的,否則,服務器會重新創建一個session,自然,sessionId也就不同了,這段代碼的輸出自然也會不同了。

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

有一些事情是瀏覽器幫助我們去做了,那就是:當你第一次與服務器通信時,瀏覽器會保存服務器返回的Set-Cookie這個健的值(JSESSIONID=64D21B4D69DFB3041B6375C1932BD6CB),只要你不關閉瀏覽器(徹底關閉,關閉選項卡不算),瀏覽器會從第二次向服務器發出請求開始,一直帶上這個鍵值對,發給服務器。服務器就會知道,這是同一個人(同一個會話)發起的請求。

(5)我們再注意一下:request.setAttribute("sysuser",userInfo)這句話:

當你第一次請求服務器時,這句代碼會根據服務器默認產生的session得到ID,并與sysuser=userInfo這個鍵值對掛上鉤(當然,userInfo可以是任何對象),保證唯一關聯,檢測用戶是否登錄就是這樣實現的。

我一定要聲明一點:保持一個會話與用戶是否登錄是沒有任何關系的。

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

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

//在與服務器通信前設置sessionId,維持唯一的一個會話

if?(Constant.sessionID?!=?null)?{

hc.setRequestProperty("Cookie",?AppContext.CurrentAppContext.sessionID);

}

//在與服務器通信前設置sessionId,維持唯一的一個會話

if (Constant.sessionID != null) {

hc.setRequestProperty("Cookie", AppContext.CurrentAppContext.sessionID);

}

(2)

A:只向服務器讀數據,不向服務寫數據,B:先向服務器寫數據,再從服務器讀數據

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

//每次與服務器通信后,保存?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超時,?will?get?new?sessionid,?but?you?must?login?again");

//設置為未登錄狀態

Constant.isLogin?=?false;

}

Constant.sessionID?=?jsessionId;

}

//每次與服務器通信后,保存 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超時, will get new sessionid, but you must login again");

//設置為未登錄狀態

Constant.isLogin = false;

}

Constant.sessionID = jsessionId;

}

這樣就可以保持一個會話了。

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

引用一段話:sun幫我們想到了,所以提供了2個方法來使事情變得簡單:response.encodeURL()和response.encodeRedirectURL()。這2個方法會判斷cookie是否可用,如果禁用了會解析出url中的jsessionid,并連接到指定的url后面,如果沒有找到jessionid會自動幫我們生成一個。至于為什么要有2個方法?這2個方法有什么不同?google了一下,說是這2個方法在判斷是否要包含jsessionid的邏輯上會稍有不同。在調用 HttpServletResponse.sendRedirect前,應該先調用encodeRedirectURL()方法,否則可能會丟失 Sesssion信息。這2個方法的使用方法如:response.sendRedirect(response.encodeURL("/myapp /input.jsp"));。如果cookie沒有禁用,我們在瀏覽器地址欄中看到的地址是這樣的:/myapp/input.jsp,如果禁用了 cookie,我們會看到:/myapp /input.jsp;jsessionid=73E6B2470C91A433A6698C7681FD44F4。所以,我們在寫web應用的時候,為了保險起見,應該在程序里的每一個跳轉url上都使用這2個方法,來保證session的可用性。

總結

以上是生活随笔為你收集整理的java 重写session_关于session的实现:cookie与url重写的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: www伊人网| 亚州av免费 | 日本综合久久 | 已满十八岁免费观看全集动漫 | 天堂在线中文在线 | 很黄很污的视频网站 | 一进一出好爽视频 | 免费一区二区在线观看 | 阿拉伯性视频xxxx | 成了校长的性脔h文 | 中文字字幕在线中文乱码电影 | www成人在线| 欧美日韩你懂的 | 日韩电影福利 | 色悠悠网 | 国产人妖ts重口系列网站观看 | 国产777| 69精品在线 | 亚洲综合精品国产一区二区三区 | 最近中文字幕在线视频 | 中文字幕在线观看不卡 | 啦啦啦免费高清视频在线观看 | 99r热 | 欧美精品观看 | 成人在线观看免费网站 | brazzers欧美一区二区 | 国产欧美亚洲精品 | 成人免费看片98欧美 | 天堂精品一区 | 美女被变态侵犯 | 国产天堂av | 日韩黄色在线播放 | 久草青青视频 | 日韩一区二区三区视频在线 | 精品一区在线看 | 在线日韩免费 | 囯产精品一品二区三区 | 日韩欧美黄色网址 | 日本女人性视频 | 欧美一区二区在线视频 | av永久免费在线观看 | 亚洲一区二区三区四区在线观看 | 少妇闺蜜换浪荡h肉辣文 | 国产网址 | 伊人久久免费视频 | 一区二区三区免费观看视频 | 永久精品网站 | 99热播精品 | 国产精品久久久久久白浆 | www.蜜臀av| 另类少妇人与禽zozz0性伦 | 国产又粗又黄又爽视频 | 男人视频网站 | 亚洲视频一区 | 久久人人妻人人人人妻性色av | 亚洲大胆人体 | 色呦呦网站在线观看 | 歪歪6080 | 国产视频1区| 亚洲s码欧洲m码国产av | 加勒比毛片 | 黑人精品xxx一区一二区 | 日本不卡免费 | 亚洲乱乱 | 在线免费av播放 | 欧美三级久久久 | 欧美日韩成人一区 | 夫妻精品 | 国产黄色一级 | 91人人爽 | 亚洲看看 | 免费黄色a | 欧美激情一二区 | 黄色一级视频免费观看 | 91在线亚洲 | 麻豆免费在线观看 | 青青草91视频 | 91五月天| 无码国产精品一区二区免费式直播 | 亚洲一区日韩 | 久久久久久久久久久福利 | 黄色网址在线免费观看 | a级无遮挡超级高清-在线观看 | 精品免费一区二区 | 久久大伊人 | 免费看一级一片 | 国产欧美视频在线 | 蜜桃av成人永久免费 | 国产乡下妇女做爰视频 | 韩国无码一区二区三区精品 | 91视频播放器 | 中文字幕在线观看91 | 农村少妇无套内谢粗又长 | 18精品爽国产白嫩精品 | www国产黄色 | 日本亲近相奷中文字幕 | 青青视频免费在线观看 | 中文永久免费观看 | 91毛片视频 |