青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

輕盈小刀-LUA

突破C++的局限,讓編程語言大同
隨筆 - 13, 文章 - 1, 評論 - 13, 引用 - 0
數據加載中……

理解session機制

session機制是一種服務器端的機制,服務器使用一種類似于散列表的結構(也可能就是使用散列表)來保存信息。

當程序需要為某個客戶端的請求創建一個session的時候,服務器首先檢查這個客戶端的請求里是否已包含了一個session標識 - 稱為 session id,如果已包含一個session id則說明以前已經為此客戶端創建過session,服務器就按照session id把這個 session檢索出來使用(如果檢索不到,可能會新建一個),如果客戶端請求不包含session id,則為此客戶端創建一個session并且生成一個與此session相關聯的session id,session id的值應該是一個既不會重復,又不容易被找到規律以仿造的字符串,這個 session id將被在本次響應中返回給客戶端保存。

保存這個session id的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動的按照規則把這個標識發揮給服務器。一般這個cookie的名字都是類似于SEEESIONID,而。比如weblogic對于web應用程序生成的cookie,JSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是 JSESSIONID。

由于cookie可以被人為的禁止,必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞回服務器。經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的后面,附加方式也有兩種,一種是作為URL路徑的附加信息,表現形式為http://...../xxx;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
另一種是作為查詢字符串附加在URL后面,表現形式為http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
這兩種方式對于用戶來說是沒有區別的,只是服務器在解析的時候處理的方式不同,采用第一種方式也有利于把session id的信息和正常程序參數區分開來。
為了在整個交互過程中始終保持狀態,就必須在每個客戶端可能請求的路徑后面都包含這個session id。

另一種技術叫做表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時能夠把session id傳遞回服務器。比如下面的表單
<form name="testform" action="/xxx">
<input type="text">
</form>
在被傳遞給客戶端之前將被改寫成
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
這種技術現在已較少應用,筆者接觸過的很古老的iPlanet6(SunONE應用服務器的前身)就使用了這種技術。
實際上這種技術可以簡單的用對action應用URL重寫來代替。

在談論session機制的時候,常常聽到這樣一種誤解“只要關閉瀏覽器,session就消失了”。其實可以想象一下會員卡的例子,除非顧客主動對店家提出銷卡,否則店家絕對不會輕易刪除顧客的資料。對session來說也是一樣的,除非程序通知服務器刪除一個session,否則服務器會一直保留,程序一般都是在用戶做log off的時候發個指令去刪除session。然而瀏覽器從來不會主動在關閉之前通知服務器它將要關閉,因此服務器根本不會有機會知道瀏覽器已經關閉,之所以會有這種錯覺,是大部分session機制都使用會話cookie來保存session id,而關閉瀏覽器后這個 session id就消失了,再次連接服務器時也就無法找到原來的session。如果服務器設置的cookie被保存到硬盤上,或者使用某種手段改寫瀏覽器發出的HTTP請求頭,把原來的session id發送給服務器,則再次打開瀏覽器仍然能夠找到原來的session。

恰恰是由于關閉瀏覽器不會導致session被刪除,迫使服務器為seesion設置了一個失效時間,當距離客戶端上一次使用session的時間超過這個失效時間時,服務器就可以認為客戶端已經停止了活動,才會把session刪除以節省存儲空間。

五、理解javax.servlet.http.HttpSession
HttpSession是Java平臺對session機制的實現規范,因為它僅僅是個接口,具體到每個web應用服務器的提供商,除了對規范支持之外,仍然會有一些規范里沒有規定的細微差異。這里我們以BEA的Weblogic Server8.1作為例子來演示。

首先,Weblogic Server提供了一系列的參數來控制它的HttpSession的實現,包括使用cookie的開關選項,使用URL重寫的開關選項,session持久化的設置,session失效時間的設置,以及針對cookie的各種設置,比如設置cookie的名字、路徑、域, cookie的生存時間等。

一般情況下,session都是存儲在內存里,當服務器進程被停止或者重啟的時候,內存里的session也會被清空,如果設置了session的持久化特性,服務器就會把session保存到硬盤上,當服務器進程重新啟動或這些信息將能夠被再次使用, Weblogic Server支持的持久性方式包括文件、數據庫、客戶端cookie保存和復制。

復制嚴格說來不算持久化保存,因為session實際上還是保存在內存里,不過同樣的信息被復制到各個cluster內的服務器進程中,這樣即使某個服務器進程停止工作也仍然可以從其他進程中取得session。

cookie生存時間的設置則會影響瀏覽器生成的cookie是否是一個會話cookie。默認是使用會話cookie。有興趣的可以用它來試驗我們在第四節里提到的那個誤解。

cookie的路徑對于web應用程序來說是一個非常重要的選項,Weblogic Server對這個選項的默認處理方式使得它與其他服務器有明顯的區別。后面我們會專題討論。

關于session的設置參考[5] http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html#1036869

六、HttpSession常見問題
(在本小節中session的含義為⑤和⑥的混合)


1、session在何時被創建
一個常見的誤解是以為session在有客戶端訪問時就被創建,然而事實是直到某server端程序調用 HttpServletRequest.getSession(true)這樣的語句時才被創建,注意如果JSP沒有顯示的使用 <% @page session="false"%> 關閉session,則JSP文件在編譯成Servlet時將會自動加上這樣一條語句 HttpSession session = HttpServletRequest.getSession(true);這也是JSP中隱含的 session對象的來歷。

由于session會消耗內存資源,因此,如果不打算使用session,應該在所有的JSP中關閉它。

2、session何時被刪除
綜合前面的討論,session在下列情況下被刪除a.程序調用HttpSession.invalidate();或b.距離上一次收到客戶端發送的session id時間間隔超過了session的超時設置;或c.服務器進程被停止(非持久session)

3、如何做到在瀏覽器關閉時刪除session
嚴格的講,做不到這一點??梢宰鲆稽c努力的辦法是在所有的客戶端頁面里使用javascript代碼window.oncolose來監視瀏覽器的關閉動作,然后向服務器發送一個請求來刪除session。但是對于瀏覽器崩潰或者強行殺死進程這些非常規手段仍然無能為力。

4、有個HttpSessionListener是怎么回事
你可以創建這樣的listener去監控session的創建和銷毀事件,使得在發生這樣的事件時你可以做一些相應的工作。注意是session的創建和銷毀動作觸發listener,而不是相反。類似的與HttpSession有關的listener還有 HttpSessionBindingListener,HttpSessionActivationListener和 HttpSessionAttributeListener。

5、存放在session中的對象必須是可序列化的嗎
不是必需的。要求對象可序列化只是為了session能夠在集群中被復制或者能夠持久保存或者在必要時server能夠暫時把session交換出內存。在 Weblogic Server的session中放置一個不可序列化的對象在控制臺上會收到一個警告。我所用過的某個iPlanet版本如果 session中有不可序列化的對象,在session銷毀時會有一個Exception,很奇怪。

6、如何才能正確的應付客戶端禁止cookie的可能性
對所有的URL使用URL重寫,包括超鏈接,form的action,和重定向的URL,具體做法參見[6]
http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770

7、開兩個瀏覽器窗口訪問應用程序會使用同一個session還是不同的session
參見第三小節對cookie的討論,對session來說是只認id不認人,因此不同的瀏覽器,不同的窗口打開方式以及不同的cookie存儲方式都會對這個問題的答案有影響。

8、如何防止用戶打開兩個瀏覽器窗口操作導致的session混亂
這個問題與防止表單多次提交是類似的,可以通過設置客戶端的令牌來解決。就是在服務器每次生成一個不同的id返回給客戶端,同時保存在session里,客戶端提交表單時必須把這個id也返回服務器,程序首先比較返回的id與保存在session里的值是否一致,如果不一致則說明本次操作已經被提交過了??梢詤⒖础禞2EE核心模式》關于表示層模式的部分。需要注意的是對于使用javascript window.open打開的窗口,一般不設置這個id,或者使用單獨的id,以防主窗口無法操作,建議不要再window.open打開的窗口里做修改操作,這樣就可以不用設置。

9、為什么在Weblogic Server中改變session的值后要重新調用一次session.setValue
做這個動作主要是為了在集群環境中提示Weblogic Server session中的值發生了改變,需要向其他服務器進程復制新的session值。

10、為什么session不見了
排除session正常失效的因素之外,服務器本身的可能性應該是微乎其微的,雖然筆者在iPlanet6SP1加若干補丁的Solaris版本上倒也遇到過;瀏覽器插件的可能性次之,筆者也遇到過3721插件造成的問題;理論上防火墻或者代理服務器在cookie處理上也有可能會出現問題。
出現這一問題的大部分原因都是程序的錯誤,最常見的就是在一個應用程序中去訪問另外一個應用程序。我們在下一節討論這個問題。

七、跨應用程序的session共享

常常有這樣的情況,一個大項目被分割成若干小項目開發,為了能夠互不干擾,要求每個小項目作為一個單獨的web應用程序開發,可是到了最后突然發現某幾個小項目之間需要共享一些信息,或者想使用session來實現SSO(single sign on),在session中保存login的用戶信息,最自然的要求是應用程序間能夠訪問彼此的session。

然而按照Servlet規范,session的作用范圍應該僅僅限于當前應用程序下,不同的應用程序之間是不能夠互相訪問對方的session的。各個應用服務器從實際效果上都遵守了這一規范,但是實現的細節卻可能各有不同,因此解決跨應用程序session共享的方法也各不相同。

首先來看一下Tomcat是如何實現web應用程序之間session的隔離的,從 Tomcat設置的cookie路徑來看,它對不同的應用程序設置的cookie路徑是不同的,這樣不同的應用程序所用的session id是不同的,因此即使在同一個瀏覽器窗口里訪問不同的應用程序,發送給服務器的session id也可以是不同的。


  

根據這個特性,我們可以推測Tomcat中session的內存結構大致如下。




筆者以前用過的iPlanet也采用的是同樣的方式,估計SunONE與iPlanet之間不會有太大的差別。對于這種方式的服務器,解決的思路很簡單,實際實行起來也不難。要么讓所有的應用程序共享一個session id,要么讓應用程序能夠獲得其他應用程序的session id。

iPlanet中有一種很簡單的方法來實現共享一個session id,那就是把各個應用程序的cookie路徑都設為/(實際上應該是/NASApp,對于應用程序來講它的作用相當于根)。
<session-info>
<path>/NASApp</path>
</session-info>

需要注意的是,操作共享的session應該遵循一些編程約定,比如在session attribute名字的前面加上應用程序的前綴,使得 setAttribute("name", "neo")變成setAttribute("app1.name", "neo"),以防止命名空間沖突,導致互相覆蓋。


在Tomcat中則沒有這么方便的選擇。在Tomcat版本3上,我們還可以有一些手段來共享session。對于版本4以上的Tomcat,目前筆者尚未發現簡單的辦法。只能借助于第三方的力量,比如使用文件、數據庫、JMS或者客戶端cookie,URL參數或者隱藏字段等手段。

我們再看一下Weblogic Server是如何處理session的。


  

從截屏畫面上可以看到Weblogic Server對所有的應用程序設置的cookie的路徑都是/,這是不是意味著在Weblogic Server中默認的就可以共享session了呢?然而一個小實驗即可證明即使不同的應用程序使用的是同一個session,各個應用程序仍然只能訪問自己所設置的那些屬性。這說明Weblogic Server中的session的內存結構可能如下




對于這樣一種結構,在 session機制本身上來解決session共享的問題應該是不可能的了。除了借助于第三方的力量,比如使用文件、數據庫、JMS或者客戶端 cookie,URL參數或者隱藏字段等手段,還有一種較為方便的做法,就是把一個應用程序的session放到ServletContext中,這樣另外一個應用程序就可以從ServletContext中取得前一個應用程序的引用。示例代碼如下,

應用程序A
context.setAttribute("appA", session); 

應用程序B
contextA = context.getContext("/appA");
HttpSession sessionA = (HttpSession)contextA.getAttribute("appA"); 

值得注意的是這種用法不可移植,因為根據ServletContext的JavaDoc,應用服務器可以處于安全的原因對于context.getContext("/appA");返回空值,以上做法在Weblogic Server 8.1中通過。

那么Weblogic Server為什么要把所有的應用程序的cookie路徑都設為/呢?原來是為了SSO,凡是共享這個session的應用程序都可以共享認證的信息。一個簡單的實驗就可以證明這一點,修改首先登錄的那個應用程序的描述符weblogic.xml,把cookie路徑修改為/appA 訪問另外一個應用程序會重新要求登錄,即使是反過來,先訪問cookie路徑為/的應用程序,再訪問修改過路徑的這個,雖然不再提示登錄,但是登錄的用戶信息也會丟失。注意做這個實驗時認證方式應該使用FORM,因為瀏覽器和web服務器對basic認證方式有其他的處理方式,第二次請求的認證不是通過 session來實現的。具體請參看[7] secion 14.8 Authorization,你可以修改所附的示例程序來做這些試驗。

八、總結
session機制本身并不復雜,然而其實現和配置上的靈活性卻使得具體情況復雜多變。這也要求我們不能把僅僅某一次的經驗或者某一個瀏覽器,服務器的經驗當作普遍適用的經驗,而是始終需要具體情況具體分析。
摘要:雖然session機制在web應用程序中被采用已經很長時間了,但是仍然有很多人不清楚session機制的本質,以至不能正確的應用這一技術。本文將詳細討論session的工作機制并且對在Java web application中應用session機制時常見的問題作出解答。

posted on 2007-12-19 23:14 絕對在乎你 閱讀(288) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产一区二区久久| 久久精品男女| 欧美96在线丨欧| 一本一本久久a久久精品牛牛影视| 欧美日韩一区三区| 性欧美1819性猛交| 99av国产精品欲麻豆| 麻豆乱码国产一区二区三区| 亚洲视频一二区| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 欧美日韩不卡合集视频| 亚洲高清在线| 久久精品国产99国产精品澳门| 日韩天堂在线视频| 亚洲最新在线| 亚洲视频在线播放| 91久久久精品| 一本色道88久久加勒比精品| 亚洲国产欧美精品| 99综合在线| 亚洲午夜视频在线| 午夜在线a亚洲v天堂网2018| 久久久久久有精品国产| 久久亚洲一区二区三区四区| 欧美大片在线观看一区二区| 欧美片在线播放| 国产精品一区二区视频| 欧美人成网站| 激情欧美一区二区三区在线观看| 日韩午夜中文字幕| 羞羞色国产精品| 亚洲精品国精品久久99热| 美女国产一区| 亚洲欧美一区二区精品久久久 | 亚洲精品影视| 久久精品中文字幕一区| 亚洲二区在线视频| 午夜在线a亚洲v天堂网2018| 欧美伊人久久| 这里只有视频精品| 欧美v日韩v国产v| 国产主播一区二区| 亚洲一区精品在线| 久久成人精品一区二区三区| 亚洲久久成人| 欧美福利视频在线观看| 悠悠资源网亚洲青| 狠狠色狠狠色综合系列| 羞羞色国产精品| 欧美一区二区观看视频| 国产亚洲观看| 美女日韩欧美| 日韩小视频在线观看| 欧美成人69| 精品96久久久久久中文字幕无| 久久精品最新地址| 久久九九国产精品| 亚洲欧美激情诱惑| 欧美精品一区二区三| 欧美亚洲一区二区在线| 亚洲免费小视频| 伊人久久婷婷色综合98网| 欧美aaa级| 国产精品久久国产精品99gif| 亚洲欧美一区二区三区在线| 亚洲欧美怡红院| 在线精品一区二区| 美女任你摸久久| 国产精品嫩草99a| 欧美精品一区在线观看| 亚洲第一狼人社区| 久久综合久久久| 欧美mv日韩mv国产网站app| 最近中文字幕日韩精品| 亚洲级视频在线观看免费1级| 午夜伦欧美伦电影理论片| 亚洲一区二区精品视频| 欧美日产国产成人免费图片| 久久天天狠狠| 亚洲国内自拍| 欧美日韩国内| 亚洲欧美日韩视频二区| 午夜精品美女久久久久av福利| 国产精品av久久久久久麻豆网| 亚洲一品av免费观看| 欧美一区二区三区免费在线看| 国产日韩欧美在线一区| 久久av一区| 亚洲老司机av| 久久综合给合久久狠狠色 | 亚洲欧美日韩精品久久久久| 欧美在线视屏| 亚洲精品一区二区三区不| 国产精品久久久久久模特| 欧美一区激情| 亚洲一区二区免费视频| 免费看的黄色欧美网站| 在线综合亚洲| 亚洲日本乱码在线观看| 国产精品久久久久一区二区三区共 | 亚洲一区二区三区在线播放| 国产专区欧美专区| 国产精品mm| 欧美日韩亚洲一区二区三区四区| 久久久国产午夜精品| 亚洲一区二区久久| 一区二区三区欧美| 日韩午夜激情av| 亚洲精品男同| 伊人成人开心激情综合网| 国产欧美午夜| 国内精品久久久久影院色| 国产精品视频区| 国产欧美va欧美不卡在线| 国产欧美日韩伦理| 国产一区二区三区无遮挡| 欧美在线日韩| 久久久免费av| 久久五月激情| 欧美成人精品不卡视频在线观看 | 亚洲欧美日韩第一区| 亚洲欧美成aⅴ人在线观看| 亚洲欧美一级二级三级| 欧美亚洲免费| 男女激情久久| 一区二区三区高清不卡| 亚洲免费在线播放| 久久亚洲一区二区三区四区| 欧美精品久久99| 国产精品亚洲不卡a| 国内外成人在线视频| 亚洲区在线播放| 午夜电影亚洲| 91久久中文| 久久精品一区蜜桃臀影院 | 一本久道综合久久精品| 亚洲一区欧美二区| 久久久久久久久伊人| 欧美不卡视频一区| 国产片一区二区| 日韩视频中文字幕| 久久免费精品视频| 亚洲欧美另类国产| 国产精品你懂的在线| 午夜视频在线观看一区| 蜜臀久久99精品久久久画质超高清| 国产精品一区久久久久| 中国成人亚色综合网站| 欧美国产视频日韩| 在线高清一区| 欧美激情亚洲另类| 久久影院亚洲| 日韩一级欧洲| 日韩亚洲不卡在线| 欧美亚洲第一页| 久久精品免费| 欧美成人亚洲成人日韩成人| 亚洲高清电影| 一片黄亚洲嫩模| 国产日韩欧美一区在线| 嫩草国产精品入口| 性欧美大战久久久久久久久| 久久久精品999| 欧美国产一区二区在线观看| 一个色综合av| 99精品欧美一区二区三区| 久久精品视频va| 久久久久99| 在线观看亚洲视频| 亚洲欧美综合v| 亚洲国产一区二区精品专区| 99综合在线| 亚洲视频每日更新| 欧美激情1区2区| 美女日韩欧美| 在线 亚洲欧美在线综合一区| 在线亚洲欧美| 在线视频你懂得一区| 欧美暴力喷水在线| 久久久久一区二区三区| 国产视频久久网| 欧美亚洲免费| 久久久青草青青国产亚洲免观| 国产精品久久国产精品99gif| 亚洲经典三级| 中日韩午夜理伦电影免费| 欧美日韩一区二区三区在线视频| 模特精品裸拍一区| 国产精品爽黄69| 麻豆成人综合网| 亚洲精品在线电影| 欧美日韩hd| 一区二区三区视频在线观看| 午夜伦欧美伦电影理论片| 国产精品欧美激情| 欧美成人激情视频免费观看| 亚洲日本aⅴ片在线观看香蕉| 亚洲免费人成在线视频观看| 红桃视频欧美| 欧美揉bbbbb揉bbbbb|