本文討論的語境是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,比如
logout
,這個tag功能與html:rewrite相似,也有href屬性,生成帶有
標簽的html內容。
,html:form沒有href屬性,只有action屬性。 3.假若沒有使用任何框架,則可以使用jstl提供的url重寫功能 jstl提供了標簽來實現c:url,比如
,這個也會根據瀏覽器是否支持cookie,來生成帶有jsessionid屬性的url。 相信通過上面的總結,是我們對怎么使用session與cookie有更深入的認識。記住,在用jsp/servlet實現系統的時候,盡量不要自己寫
標簽,最好使用系統框架自帶的標簽來實現,否則瀏覽器取消cookie功能的話,系統不支持url重寫功能。