上一篇文章 |
技術(shù)討論 |
下一篇文章 Java基礎-關(guān)于session的詳細解釋 (2)
[原創(chuàng )] 2006-04-11 | 發(fā)表者: zol_xiao
5、存放在session中的對象必須是可序列化的嗎
不是必需的。要求對象可序列化只是為了session能夠在集群中被復制或者能夠持久保存或者在必要時(shí)server能夠暫時(shí)把session交換出內存。在Weblogic Server的session中放置一個(gè)不可序列化的對象在控制臺上會(huì )收到一個(gè)警告。我所用過(guò)的某個(gè)iPlanet版本如果session中有不可序列化的對象,在session銷(xiāo)毀時(shí)會(huì )有一個(gè)Exception,很奇怪。
6、如何才能正確的應付客戶(hù)端禁止cookie的可能性
對所有的URL使用URL重寫(xiě),包括超鏈接,form的action,和重定向的URL,具體做法參見(jiàn)[6]
http://e-docs.bea.com/wls/docs70/webapp/sessions.html#1007707、開(kāi)兩個(gè)瀏覽器窗口訪(fǎng)問(wèn)應用程序會(huì )使用同一個(gè)session還是不同的session
參見(jiàn)第三小節對cookie的討論,對session來(lái)說(shuō)是只認id不認人,因此不同的瀏覽器,不同的窗口打開(kāi)方式以及不同的cookie存儲方式都會(huì )對這個(gè)問(wèn)題的答案有影響。
8、如何防止用戶(hù)打開(kāi)兩個(gè)瀏覽器窗口操作導致的session混亂
這個(gè)問(wèn)題與防止表單多次提交是類(lèi)似的,可以通過(guò)設置客戶(hù)端的令牌來(lái)解決。就是在服務(wù)器每次生成一個(gè)不同的id返回給客戶(hù)端,同時(shí)保存在session里,客戶(hù)端提交表單時(shí)必須把這個(gè)id也返回服務(wù)器,程序首先比較返回的id與保存在session里的值是否一致,如果不一致則說(shuō)明本次操作已經(jīng)被提交過(guò)了??梢詤⒖础禞2EE核心模式》關(guān)于表示層模式的部分。需要注意的是對于使用javascript window.open打開(kāi)的窗口,一般不設置這個(gè)id,或者使用單獨的id,以防主窗口無(wú)法操作,建議不要再window.open打開(kāi)的窗口里做修改操作,這樣就可以不用設置。
9、為什么在Weblogic Server中改變session的值后要重新調用一次session.setValue
做這個(gè)動(dòng)作主要是為了在集群環(huán)境中提示W(wǎng)eblogic Server session中的值發(fā)生了改變,需要向其他服務(wù)器進(jìn)程復制新的session值。
10、為什么session不見(jiàn)了
排除session正常失效的因素之外,服務(wù)器本身的可能性應該是微乎其微的,雖然筆者在iPlanet6SP1加若干補丁的Solaris版本上倒也遇到過(guò);瀏覽器插件的可能性次之,筆者也遇到過(guò)3721插件造成的問(wèn)題;理論上防火墻或者代理服務(wù)器在cookie處理上也有可能會(huì )出現問(wèn)題。
出現這一問(wèn)題的大部分原因都是程序的錯誤,最常見(jiàn)的就是在一個(gè)應用程序中去訪(fǎng)問(wèn)另外一個(gè)應用程序。我們在下一節討論這個(gè)問(wèn)題。
七、跨應用程序的session共享
常常有這樣的情況,一個(gè)大項目被分割成若干小項目開(kāi)發(fā),為了能夠互不干擾,要求每個(gè)小項目作為一個(gè)單獨的web應用程序開(kāi)發(fā),可是到了最后突然發(fā)現某幾個(gè)小項目之間需要共享一些信息,或者想使用session來(lái)實(shí)現SSO(single sign on),在session中保存login的用戶(hù)信息,最自然的要求是應用程序間能夠訪(fǎng)問(wèn)彼此的session。
然而按照Servlet規范,session的作用范圍應該僅僅限于當前應用程序下,不同的應用程序之間是不能夠互相訪(fǎng)問(wèn)對方的session的。各個(gè)應用服務(wù)器從實(shí)際效果上都遵守了這一規范,但是實(shí)現的細節卻可能各有不同,因此解決跨應用程序session共享的方法也各不相同。
首先來(lái)看一下Tomcat是如何實(shí)現web應用程序之間session的隔離的,從Tomcat設置的cookie路徑來(lái)看,它對不同的應用程序設置的cookie路徑是不同的,這樣不同的應用程序所用的session id是不同的,因此即使在同一個(gè)瀏覽器窗口里訪(fǎng)問(wèn)不同的應用程序,發(fā)送給服務(wù)器的session id也可以是不同的。
根據這個(gè)特性,我們可以推測Tomcat中session的內存結構大致如下。
筆者以前用過(guò)的iPlanet也采用的是同樣的方式,估計SunONE與iPlanet之間不會(huì )有太大的差別。對于這種方式的服務(wù)器,解決的思路很簡(jiǎn)單,實(shí)際實(shí)行起來(lái)也不難。要么讓所有的應用程序共享一個(gè)session id,要么讓?xiě)贸绦蚰軌颢@得其他應用程序的session id。
iPlanet中有一種很簡(jiǎn)單的方法來(lái)實(shí)現共享一個(gè)session id,那就是把各個(gè)應用程序的cookie路徑都設為/(實(shí)際上應該是/NASApp,對于應用程序來(lái)講它的作用相當于根)。
/NASApp
需要注意的是,操作共享的session應該遵循一些編程約定,比如在session attribute名字的前面加上應用程序的前綴,使得setAttribute("name", "neo")變成setAttribute("app1.name", "neo"),以防止命名空間沖突,導致互相覆蓋。
在Tomcat中則沒(méi)有這么方便的選擇。在Tomcat版本3上,我們還可以有一些手段來(lái)共享session。對于版本4以上的Tomcat,目前筆者尚未發(fā)現簡(jiǎn)單的辦法。只能借助于第三方的力量,比如使用文件、數據庫、JMS或者客戶(hù)端cookie,URL參數或者隱藏字段等手段。
我們再看一下Weblogic Server是如何處理session的。
從截屏畫(huà)面上可以看到Weblogic Server對所有的應用程序設置的cookie的路徑都是/,這是不是意味著(zhù)在Weblogic Server中默認的就可以共享session了呢?然而一個(gè)小實(shí)驗即可證明即使不同的應用程序使用的是同一個(gè)session,各個(gè)應用程序仍然只能訪(fǎng)問(wèn)自己所設置的那些屬性。這說(shuō)明Weblogic Server中的session的內存結構可能如下
對于這樣一種結構,在session機制本身上來(lái)解決session共享的問(wèn)題應該是不可能的了。除了借助于第三方的力量,比如使用文件、數據庫、JMS或者客戶(hù)端cookie,URL參數或者隱藏字段等手段,還有一種較為方便的做法,就是把一個(gè)應用程序的session放到ServletContext中,這樣另外一個(gè)應用程序就可以從ServletContext中取得前一個(gè)應用程序的引用。示例代碼如下,
應用程序A
context.setAttribute("appA", session);
應用程序B
contextA = context.getContext("/appA");
HttpSession sessionA = (HttpSession)contextA.getAttribute("appA");
值得注意的是這種用法不可移植,因為根據ServletContext的JavaDoc,應用服務(wù)器可以處于安全的原因對于context.getContext("/appA");返回空值,以上做法在Weblogic Server 8.1中通過(guò)。
那么Weblogic Server為什么要把所有的應用程序的cookie路徑都設為/呢?原來(lái)是為了SSO,凡是共享這個(gè)session的應用程序都可以共享認證的信息。一個(gè)簡(jiǎn)單的實(shí)驗就可以證明這一點(diǎn),修改首先登錄的那個(gè)應用程序的描述符weblogic.xml,把cookie路徑修改為/appA訪(fǎng)問(wèn)另外一個(gè)應用程序會(huì )重新要求登錄,即使是反過(guò)來(lái),先訪(fǎng)問(wèn)cookie路徑為/的應用程序,再訪(fǎng)問(wèn)修改過(guò)路徑的這個(gè),雖然不再提示登錄,但是登錄的用戶(hù)信息也會(huì )丟失。注意做這個(gè)實(shí)驗時(shí)認證方式應該使用FORM,因為瀏覽器和web服務(wù)器對basic認證方式有其他的處理方式,第二次請求的認證不是通過(guò)session來(lái)實(shí)現的。具體請參看[7] secion 14.8 Authorization,你可以修改所附的示例程序來(lái)做這些試驗。
八、總結
session機制本身并不復雜,然而其實(shí)現和配置上的靈活性卻使得具體情況復雜多變。這也要求我們不能把僅僅某一次的經(jīng)驗或者某一個(gè)瀏覽器,服務(wù)器的經(jīng)驗當作普遍適用的經(jīng)驗,而是始終需要具體情況具體分析。
本文章引用通告地址(TrackBack Ping URL)為:
http://blog.zol.com.cn/portal/personShowArticle.do?articleId=16951