....
http://blog.csdn.net/xgx1985xgx/article/details/6586690
之前做一個頁面時發現如果:A站iframe引用B站的頁面時(A,B不在同一台服務器),如果在這個Iframe中B的頁面做了跳轉,當用IE瀏覽的時候會導致server 的session丟失,原因是IE的保護機制禁止將iframe中得到的sid傳遞給下一個頁面。
解決方法比較簡單:在B被引用的頁面上添加JSP代碼:
- <%
- response.setHeader("P3P","CP=CAO PSA OUR");
- %>
- <p>1.頁面里的COOKIE不能是瀏覽器進程的COOKIE(包括驗證票和不設置超時時間的COOKIE),否則跨域會取不到.這點做跨域COOKIE的人比較少提到.不過實際上留意下幾家大學做的方案,有細微的提到他們的驗證模塊里的COOKIE是有設置超時時間的.</p><p>2.當利用IFRAME時,記得要在相應的動態頁的頁頭添加一下P3P的信息,否則IE會自覺的把IFRAME框里的COOKIE給阻止掉,產生問題.本身不保存自然就取不到了.這個其實是FRAMESET和COOKIE的問題,用FRAME或者IFRAME都會遇到.</p><p>3.測試時輸出TRACE,會減少很多測試的工作量.</p><p><strong>只需要設置 P3P HTTP Header</strong>,在隱含 iframe 里面跨域設置 cookie 就可以成功。他們所用的內容是:</p><p>P3P: CP='CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR'</p><p>ASP直接在頭部加了頭部申明,測試有效。
- <%Response.AddHeader "P3P", "CP=CAO PSA OUR"%>
- php的話,應該是如下寫法:
- header('P3P: CP=CAO PSA OUR');
- ASP.NET的話
- 通過在代碼上加Response.AddHeader("P3P", "CP=CAO PSA OUR")或者在Window服務中將ASP.NET State Service 啟動。
- JSP:
- response.setHeader("P3P","CP=CAO PSA OUR")</p><p> </p><p> </p><p> </p>
==============================
http://liuzidong.iteye.com/blog/1132219
參考資料
1 關於WebLogic的Session丟失的問題
http://blog.csdn.net/DesignLife/article/details/2552186
2 tomcat向weblogic移植出現的問題系列 - session丟失問題
(其中一位網友回答不知是什么意思,要加什么文件)
http://netliving.iteye.com/blog/148485
3 java weblogic session 丟失
http://hi.baidu.com/leftstone/blog/item/3b34a4a19d4d0588471064f0.html
4 weblogic兩個domain中jsp相互調用session丟失解決方法
http://www.4ucode.com/Study/Topic/1159787
5 關於WebLogic的Session丟失的問題
http://hi.baidu.com/goylsf/blog/item/d2446677d71e070ab051b98d.html
6 weblogic通過代理插件weblogic.servlet.proxy.HttpProxyServlet跨域訪問導致session丟失問題的解決
http://ribbonchen.blog.163.com/blog/static/1183165052011074500877/
7 WebLogic如何設置session超時時間
http://tonyaction.blog.51cto.com/227462/201900
注意網上有很多的Webloigc不是最新的配置
位於WEB-INF/WebLogic.xml配置如下:
- <?xml version='1.0' encoding='utf-8'?>
- <weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
- http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
- http://www.bea.com/ns/weblogic/90
- http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">
- <container-descriptor>
- <prefer-web-inf-classes>true</prefer-web-inf-classes>
- </container-descriptor>
- <context-root>/</context-root>
- <session-descriptor>
- <!--WebLogic設置Session超時時間,在web.xml中去掉session超時設置 -->
- <!-- <timeout-secs>7200</timeout-secs> -->
- <cookie-name>JSESSIONID1</cookie-name>
- </session-descriptor>
- </weblogic-web-app>
一 WebLogic設置Session超時
1 web.xml
設置WEB應用程序描述符web.xml里的<session-timeout>元素。這個值以分鍾為
單位,並覆蓋weblogic.xml中的TimeoutSecs屬性
- <session-config>
- <session-timeout>30</session-timeout>
- </session-config>
此例表示Session將在54分鍾后過期
當<session-timeout>設置為-2,表示將使用在weblogic.xml中設置的
TimeoutSecs這個屬性值。
當<session-timeout>設置為-1,表示Session將永不過期,而忽略在
weblogic.xml中設置的TimeoutSecs屬性值。
該屬性值可以通過console控制台來設置
在weblgoic的console中:xxDomain->Servers->xxServer->Protocols->HTTP 中有一個關於Post Timeout的配置,但這個參數一般使用默認值即可
一般是通過Services-->JDBC-->Connection Pools-->MyConnection(你所建立的連接池名)-->Configration-->Connections 里的Inactive Connection Timeout這個參數來設置的,默認的為0,表示連接時間無限長。你可以設一個時間值,連接超過這個時間值,它會把連接強制放回連接池
- <Server AcceptBacklog="62" CompleteHTTPMessageTimeout="480"
- CompleteMessageTimeout="480" IdleC
- ListenAddress="" ListenPort="7001" Name="myserver"
- NativeIOEnabled="true" ReliableDeliveryPolicy="RMDefaultPolicy"
- ServerVersion="8.1.4.0">
是否IdleConnectionTimeout參數
2 weblogic.xml
設置WebLogic特有部署描述符weblogic.xml的<session-descriptor>元素的
TimeoutSecs屬性。這個值以秒為單位
- <session-descriptor>
- <!--WebLogic設置Session超時時間,在web.xml中去掉session超時設置 -->
- <timeout-secs>7200</timeout-secs>
- </session-descriptor>
二 防止Webloigic下的iframe的Session失效
請在Weblogic.xml添加如下代碼
- <session-descriptor>
- <cookie-name>JSESSIONID1</cookie-name>
- </session-descriptor>
原來session在服務器端生成后分配的sessionID在客戶端的保存方式是個cookie,它的生命周期在瀏覽器關閉后就會結束,而這個cookie的名字如果不特別設置,weblogic會以默認的名稱“JSESSIONID”來設置這個cookie的名稱,我兩個應用的的session cookie名字都沒有設置,客戶端在第一次通過應用A請求代理轉發到應用B時,應用B返回的同名session cookie覆蓋了客戶端原本的應用A的session cookie,所以導致了應用A session的丟失。
解決方法是,在應用B的weblogic.xml中的session descriptor標記中添加session cookie的名稱設置,使其區別於A應用的session cookie名稱.其中的cookie-name可以重命名!解決在iframe中進行跨域訪問時session丟失的問題
附件有:weblogic-web-app.xsd
==============================
http://bbs.phpchina.com/thread-90724-1-1.html
看看你的瀏覽器設置的是否支持Cookies,還有Apache用的時間與本機時間時區不同造成時差也會使Cookies丟失。
==========================
session和cookie是網站瀏覽中較為常見的兩個概念,也是比較難以辨析的兩個概念,但它們在點擊流及基於用戶瀏覽行為的網站分析中卻相當關鍵。基於網上一些文章和資料的參閱,及作者個人的應用體會,對這兩個概念做一個簡單的闡述和辨析,希望能與大家共同探討下。
session和cookie的最大區別在於session是保存在服務端的內存里面,而cookie保存於瀏覽器或客戶端文件里面;session是基於訪問的進程,記錄了一個訪問的開始到結束,當瀏覽器或進程關閉之后,session也就“消失”了,而cookie更多地被用於標識用戶,它可以是長久的,用於用戶跟蹤和識別唯一用戶(Unique Visitor)。
關於session
session被用於表示一個持續的連接狀態,在網站訪問中一般指代客戶端瀏覽器的進程從開啟到結束的過程。session其實就是網站分析的訪問(visits)度量,表示一個訪問的過程。
session的常見實現形式是會話cookie(session cookie),即未設置過期時間的cookie,這個cookie的默認生命周期為瀏覽器會話期間,只要關閉瀏覽器窗口,cookie就消失了。實現機制是當用戶發起一個請求的時候,服務器會檢查該請求中是否包含sessionid,如果未包含,則系統會創造一個名為JSESSIONID的輸出cookie返回給瀏覽器(只放入內存,並不存在硬盤中),並將其以HashTable的形式寫到服務器的內存里面;當已經包含sessionid是,服務端會檢查找到與該session相匹配的信息,如果存在則直接使用該sessionid,若不存在則重新生成新的session。這里需要注意的是session始終是有服務端創建的,並非瀏覽器自己生成的。
但是瀏覽器的cookie被禁止后session就需要用get方法的URL重寫的機制或使用POST方法提交隱藏表單的形式來實現。
這里有一個很關鍵性的注意點,即session失效時間的設置,這里要分兩方面來看:瀏覽器端和服務端。對於瀏覽器端而言,session與訪問進程直接相關,當瀏覽器被關閉時,session也隨之消失;而服務器端的session失效時間一般是人為設置的,目的是能定期地釋放內存空間,減小服務器壓力,一般的設置為當會話處於非活動狀態達20或30分鍾時清除該session,所以瀏覽器端和服務端的session並非同時消失的,session的中斷也並不一定意味着用戶一定離開了該網站。目前Google Analytics和Omniture都定義當間隔30分鍾沒有動作時,算作一次訪問結束,所以上圖中session的最后一步不只是離開,也有可能是靜止、休眠或者發呆的狀態。
還有一點需要注意,就是現在的瀏覽器好像趨向於多進程的session共享,即通過多個標簽或頁面打開多個進程訪問同一網站時共享一個session cookie,只有當瀏覽器被關閉時才會被清除,也就是你有可能在標簽中關閉了該網站,但只要瀏覽器未被關閉並且在服務器端的session未失效前重新開啟該網站,那么就還是使用原session進行瀏覽;而某些瀏覽器在打開多頁面時也可能建立獨立的session,IE8、Chrome默認都是共享session的,在IE8中可以通過菜單欄中的文件->新建會話來建立獨立session的瀏覽頁面。
關於cookie
cookie 是一小段文本信息,伴隨着用戶請求和頁面在Web服務器和瀏覽器之間傳遞。用戶每次訪問站點時,Web應用程序都可以讀取cookie包含的信息。
session的實現機制里面已經介紹了常見的方法是使用會話cookie(session cookie)的方式,而平常所說的cookie主要指的是另一類cookie——持久cookie(persistent cookies)。持久cookie是指存放於客戶端硬盤中的cookie信息(設置了一定的有效期限),當用戶訪問某網站時,瀏覽器就會在本地硬盤上查找與該網站相關聯的cookie。如果該cookie 存在,瀏覽器就將它與頁面請求一起通過HTTP報頭信息發送到您的站點,然后在系統會比對cookie中各屬性和值是否與存放在服務器端的信息一致,並根據比對結果確定用戶為“初訪者”或者“老客戶”。
持久cookie一般會保存用戶的用戶ID,該信息在用戶注冊或第一次登錄的時候由服務器生成包含域名及相關信息的cookie發送並存放到客戶端的硬盤文件上,並設置cookie的過期時間,以便於實現用戶的自動登錄和網站內容自定義。
Apache自帶的mod_usertrack模塊可以在用戶首次來到當前網站的時候給用戶種下一個唯一的cookie(較長時間過期),這個cookie是用戶首次來當前網站的IP地址加上一個隨機字符串組成的。同時在自定義WEB日志中在最后增加%{cookie}n字段可以實現cookie在apache日志中的輸出,用於數據統計與用戶跟蹤。
http://bbs.phpchina.com/thread-243469-1-1.html
具體來說cookie機制采用的是在客戶端保持狀態的方案,而session機制采用的是在服務器端保持狀態的方案。
cookie的內容主要包括:名字,值,過期時間,路徑和域。路徑與域一起構成cookie的作用范圍。若不設置過期時間,則表示這
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
實際上這種技術可以簡單的用對action應用URL重寫來代替。
考慮到安全應當使用session
考慮到減輕服務器性能方面,應當使用COOKIE
將登陸信息等重要信息存放為SESSION
其他信息如果需要保留,可以放在COOKIE中
Cookie機制采用的是在客戶端保持狀態的方案。它是在用戶端的會話狀態的存貯機制,他需要用戶打開客戶端的cookie支持。Cookie 的作用就是為了解決HTTP協議無狀態的缺陷所作的努力。Cookie是服務器請求客戶端在本地機器上存儲的小段文本,並隨每一個請求發送至同一個服務器。IETF RFC 2965 HTTP State Management Mechanism 是通用cookie規范。網絡服務器也可以通過擴展HTTP協議來實現的向客戶端分發cookie,服務器通過在HTTP的響應頭中加上一行特殊的指示 (即Set-Cookie屬性)以提示瀏覽器按照指示生成相應的cookie,並存放在內存(或文件)中以供使用。 而Session機制采用的是一種在客戶端與服務器之間保持狀態的解決方案。Session將信息保存在服務器上,用一個標識(session id)來區分是客戶端的請求所關聯的session。該標識是在session被創建的時候生成並傳遞給客戶端的,並通過用戶的瀏覽器在訪問的時候返回給服務器。由於需要傳遞和保存這樣一個標識,所以session機制可能需要借助於cookie機制來達到這個的目的,而當客戶端是可以禁用cookie機制的,所以這個標識也可能通過其他的方式來返回給服務器。 |
最近在把Tomcat下的程序遷移到Weblogic上的時候遇到了問題,我的程序中有一個過濾器,這個過濾器主要用來檢查當前用戶訪問的資源是否需要認證,如果需要認證並且沒有認證的話,則跳轉到另外一個認證服務器上去做認證,認證通過后,再跳轉回當前服務器繼續訪問請求的資源。這個過濾器在Tomcat下運行的很正常,但是遷移到Weblogic上的時候就出現頁面亂跳轉的現象,因為對程序沒有做任何改動,所以懷疑是Tomcat和Weblogic這兩個不同的Web容器在處理方式上有差別,於是就在過濾器中加入了一些輸出信息,通過觀察發現了用戶的sessionid在Weblogic上跳轉前后發生了變化,而在Tomcat上跳轉前后則不會有任何變化。頁面的跳轉是通過response.sendRedirect("xxx.jsp")來實現的,因此懷疑Weblogic在這個方法的處理上跟Tomcat上不同而導致錯誤產生(很愚蠢的懷疑,這也導致我在查找問題的方向上出現了錯誤),一直認為可以通過修改Weblogic的weblogic.xml這個文件來解決,在網上搜了很多,也在看了一天weblogic的資料,都沒有解決。后來無意中發現了一個問題,我如果訪問的資源都是本地服務器上的,那么去認證之后就不會報錯,如果是其他服務器的(其他服務器也使用同一個認證服務器做認證)則會出現上述問題,對cookie做了進一步的跟蹤,發現cookie里面的jsessionid在訪問了其他服務器之后就被修改了,也就是原來的jsessionid不見了。同樣的事情,在tomcat上就不會出現(到現在我還認為是Tomcat和Weblogic的差別)。在Google上搜索了N遍無果之后,在Baidu上終於結果了,有人遇到過跟我相同的問題,這個問題並不是Tomcat和Weblogic的差別引起的,我在查找問題原因的時候忽略了一個細節,也就是遷移到的Weblogic服務器上,和另外幾個服務器(包括認證服務器)都在同一個IP地址的不同端口下,也就是在同一個域下,而這應該就是問題的所在。具體的細節我還沒有搞清楚,但應該是訪問了同一個服務器而導致了jsessionid發生了覆蓋,解決方法很簡單
如下:兩個web使用不同的sessionid來標識,如第一個web使用jsessionid1,第二個web使用 jsessionid2就可以了。 直接在每個web程序下配置weblogic.xml
<session-descriptor>
<session-param>
<param-name>CookieName</param-name>
<param-value>JSESSIONID1</param-value>
</session-param>
</session-descriptor>
即將第一個web app的session id標識改為jsessionid1,同理將第二個改為jsessionid2
我只是修改了我的服務器上的weblogic,而沒有修改其他服務器的,以上問題得到解決了。
同樣,這也解釋了為什么在最開始的時候我發現jsessionid在Tomcat下不變,而在Weblogic上確改變了的問題
http://blog.webwlan.net/wordpress/?p=3779
我在同一個weblogic下創建了兩個domain,部署了兩個系統A和B。其中系統A有一個按鈕可打開系統B,並自動登錄。通過A系統打開B系 統后session會發生無規律丟失的情況。經過兩天的研究,baidu,goolge了無數次后找到了一個帖子,里面寫了一下方法:
這主要是sessionid在影響,你登錄第一個web時默認使用jsessionid來記錄session id的,放在cookie里 或者url后面,登錄第二個時還是默認使用的jsessionid來做的,這樣第二個會覆蓋第一個jsessionid,所 以表現為session丟失了。
解決辦法如下:兩個web使用不同的sessionid來標識,如第一個web使用jsessionid1,第二個web使用 jsessionid2就可以了。 直接在每個web程序下配置weblogic.xml
<session-descriptor>
<session-param>
<param-name>CookieName</param-name>
<param-value>JSESSIONID1</param-value>
</session-param>
</session-descriptor>
即將第一個web app的session id標識改為jsessionid1,同理將第二個改為jsessionid2 ,這樣你再來做你 的就不會有問題了。
http://itindex.net/blog/2010/06/18/1276830937324.html
問題描述
集成項目HT實施過程中碰到這樣的問題,本次集成是把兩個不同的應用集成到同一個頁面框架下,部署方式為:
同一個Server ServerName = Server01,同一個Weblogic,分別建立兩個Domain,Domain01(port-7001)和Domain02(port-7002),將應用App1部署在Domain01,將應用App2部署在Domain02,同時啟動這兩個Domain,如果完全是默認配置,單獨訪問兩個應用是沒有問題的,但是在同一個客戶端如果訪問App1之后再訪問APP2會發現App1的Session丟失。
問題分析
客戶端在訪問App1時,Domain01會在該客戶端保留一個名為 JSessionID的Cookie,記錄了Domain01的信息,JSessionID為Weblogic cookie-name的默認值,當同一個客戶端訪問App2時,該客戶端Cookie中JSessionID的值被Domain02刷新,此時如果在之前已經打開的IE中繼續訪問App1會發現Session丟失(JSessionID已經被Domain02刷新!)。
解決方案
第一種方案
在App1和App2的weblogic.xml文件添加如下屬性
<session-descriptor>
<session-param>
<param-name>CookieName</param-name>
<param-value>myCookie1</param-value>
</session-param>
</session-descriptor>
將 的值更改為不同於默認值就可以
如果不添加這個,那么客戶端的COOKIE中保存的SESSION ID的對象名字是JSESSIONID,來自同一個SERVER上面的應用可能會造成這個SESSION ID的丟失,因為只要是WEBLOGIC產生的SESSION ID都是保存在這個名字的COOKIE中,這段配置就是把應用中的這個名字換成我們私有的,避免和其它域中的應用產生的JSESSIONID沖突。
第二種方案
訪問App1時用IP來訪問,訪問App2時用域名來訪問。
特別注意
如果應用程序部署為Cluster的模式,將無法設定,否則部署時發生錯誤。
http://tonyaction.blog.51cto.com/227462/201900
WebLogic如何設置session超時時間
設置WEB應用程序描述符web.xml里的<session-timeout>元素。這個值以分鍾為
單位,並覆蓋weblogic.xml中的TimeoutSecs屬性
<session-config>
<session-timeout>54</session-timeout>
</session-config>
此例表示Session將在54分鍾后過期
當<session-timeout>設置為-2,表示將使用在weblogic.xml中設置的
TimeoutSecs這個屬性值。
當<session-timeout>設置為-1,表示Session將永不過期,而忽略在
weblogic.xml中設置的TimeoutSecs屬性值。
該屬性值可以通過console控制台來設置
2 weblogic.xml
設置WebLogic特有部署描述符weblogic.xml的<session-descriptor>元素的
TimeoutSecs屬性。這個值以秒為單位
<session-descriptor>
<session-param>
<param-name>TimeoutSecs</param-name>
<param-value>3600</param-value>
</session-param>
</session-descriptor>
默認值是3600秒
3,jsp中控制
session.setmaxinactiveinterval(7200);
session是默認對象,可以直接引用,單位秒s
4,servlet中控制
httpsession session = request.getsession();
session.setmaxinactiveinterval(7200);
單位秒s
在weblgoic的console中:xxDomain->Servers->xxServer->Protocols->HTTP 中有一個關於Post Timeout的配置,但這個參數一般使用默認值即可
一般是通過Services-->JDBC-->Connection Pools-->MyConnection(你所建立的連接池名)-->Configration-->Connections 里的Inactive Connection Timeout這個參數來設置的,默認的為0,表示連接時間無限長。你可以設一個時間值,連接超過這個時間值,它會把連接強制放回連接池
<Server AcceptBacklog="62" CompleteHTTPMessageTimeout="480"
CompleteMessageTimeout="480" IdleC
ListenAddress="" ListenPort="7001" Name="myserver"
NativeIOEnabled="true" ReliableDeliveryPolicy="RMDefaultPolicy"
ServerVersion="8.1.4.0">
是否IdleConnectionTimeout參數
看連接池中高級選項內的Inactive Connection Timeout和Connection Reserve Timeout時多少, 把這兩項設大些試試
一個服務器上搭建了多個tomcat或者weblogic,端口不一樣,同時啟動訪問時session丟失。如:A,B兩個服務,在瀏覽器中登錄訪問A后,當前打開的瀏覽器上在開一個選項卡訪問B服務后,回過來點擊訪問A時session丟失,需要重新登錄A才可以訪問。經過資料查找,發現問題是因為:IP相同認為是同一個域,接收了B的set-cookie指令,把對應的cookie內容覆蓋了,其中包括jsessionid,造成A的session丟失。 如果IP不同,則不會發生這個問題。IP相同的兩個session對應的cookie是一樣的,而不幸的是sessionID就保存在cookie中,這樣先訪問A,再訪問B的時候,B的sessionid會覆蓋A的sessionid。這個事情沒辦法解決,所以你不要搞兩個端口,最好是搞兩個IP。原來都是cookie惹的禍,它不會區分端口,造成這多個站點不斷的后來的覆蓋前面的,從而造成session的丟失。
解決方法:
方法1:將不同的多個應用服務在不同的虛擬主機中,或者映射不同的IP進行部署。
方法2:對應tomcat服務處理方式:修改coocie的名稱保證cookie不重復,即jsessionid的不重稱,保證ip相同下sessioncookiename域名不同。
1、tomcat5修改方法
在啟動項中增加org.apache.catalina.SESSION_COOKIE_NAME參數
linux
JAVA_OPTS=’-Dorg.apache.catalina.SESSION_COOKIE_NAME=yousessionname‘win
set JAVA_OPTS=”-Dorg.apache.catalina.SESSION_COOKIE_NAME=yousessionname“
2、tomcat6和tomcat7修改方法相同
tomcat增加參數對所有Context生效,影響甚大,所以到以后的版本可以就僅針對Context設置了
在Context容器標簽上增加sessionCookieName參數
3、weblogic修改方法<Context path=”/” docBase=”webapp” reloadable=”false” sessionCookieName=”yoursessionname”></Context>
設置各個應用使用不同的cookie-name。
weblogic的設置(設置不同的cookie-name):
請在WEB-INF\Weblogic.xml添加如下代碼
<session-descriptor>
<cookie-name>JSESSIONID1</cookie-name>
</session-descriptor>
http://my.oschina.net/moyuqi/blog/98475
使用apache反向代理解決在應用A使用Iframe嵌入應用B的功能而產生的跨域問題后,應用B的功能能正常使用了。但也產生了另外一個問題:打開應用A的任何頁面都會跳轉主頁,問題原因是:session丟失。
session是通過在客戶端生成一個cookie,所有請求會帶上這個cookie。一個cookie的NAME、Domain和Path屬性值均相同,則會覆蓋,若未設置Domain域,則域為ip(不包括端口),因此應用A的session被應用B的session覆蓋了。
經測試:tomcat、weblogic、websphere的session默認都是JSESSIONID 為key來識別的,因此在沒有特別設置下,同一個域下的多個應用session會互相覆蓋。
解決辦法:
設置各個應用使用不同的cookie-name,或者將JSESSIONID的path路徑設置為不同。
1)WebLogic的Cookie相關配置:weblogic.xml
屬性名 |
默認值 | 值 |
cookie-name | JSESSIONID | 如未設置,默認為“JSESSIONID” |
cookie-path | NULL | 如未設置,默認為“/” |
cookie-domain | NULL | 如未設置,默認為發放cookie的服務器的域 |
1. <session-descriptor> 2. <session-param> 3. <param-name>CookieName</param-name> 4. <param-value>HADFCookie</param-value> 5. </session-param> 6. </session-descriptor>
2)websphere的設置(設置不同JSESSIONID的path)
應用程序->企業應用程序-> [Application Server] ->
會話管理->1.覆蓋會話管理(需打鈎).
會話管理->2.啟用 cookie(需打鈎)->修改'Cookie路徑'
3)Tomcat的設置(設置不同JSESSIONID的path)
修改tomcat/conf/server.xml:
1.tomcat5修改方法
在啟動項中增加org.apache.catalina.SESSION_COOKIE_NAME參數
linux
JAVA_OPTS=’-Dorg.apache.catalina.SESSION_COOKIE_NAME=yousessionname‘win
set JAVA_OPTS=”-Dorg.apache.catalina.SESSION_COOKIE_NAME=yousessionname“
2.tomcat6和tomcat7修改方法相同
在Context容器標簽上增加sessionCookieName參數
<Context path=”/” docBase=”webapp” reloadable=”false” sessionCookieName=”yoursessionname”></Context>
還可以加上sessionCookiePath
<Context ... sessionCookiePath="/" > ... </Context>
延伸閱讀:tomcat修改jsessionid在cookie中的名稱 http://blog.shilimin.com/338.htm
==================================================
http://blog.csdn.net/e_wsq/article/details/7555667
問題:部署3個應用(訪問IP相同,域名不同,端口不同),3個應用之間的session 相互影響
原因:session是通過在客戶端生成一個cookie,所有請求會帶上這個cookie,(例如在weblogic中默認這個cookie的名稱為JSESSIONID),例如都是發布在weblogic下,則互相訪問時,由於未設置cookie-name,默認cookie-name是JSESSIONID,因此客戶端中的cookie會互相覆蓋,從而導致session混亂
一個cookie的NAME、Domain和Path屬性值均相同,則會覆蓋,若未設置Domain域,則域為ip(不包括端口),因此三個應用的session cookie就會互相覆蓋
解決辦法:設置各個應用使用不同的cookie-name,或者將JSESSIONID的path路徑設置為不同
1)weblogic的設置(設置不同的cookie-name):
請在WEB-INF\Weblogic.xml添加如下代碼
<session-descriptor>
<cookie-name>JSESSIONID1</cookie-name>
</session-descriptor>
2)websphere的設置(設置不同JSESSIONID的path)
應用程序->企業應用程序-> [Application Server] ->
會話管理->1.覆蓋會話管理(需打鈎).
會話管理->2.啟用 cookie(需打鈎)->修改'Cookie路徑'
參考文檔:
資料一:
在將LWAP開發的應用遷移為Oracle ADF來開發的過程中,LWAP和ADF應用都部署在同一個Weblogic服務器的兩個Domain下,
當在IE中首先訪問ADF應用,然后再另外一個標簽頁中訪問LWAP應用,就會發現ADF應用出現問題,就會發現session丟失。
問題是由於客戶端訪問ADF應用時,對應的Weblogic域會保留一個名為JSessionId的Cookie,記錄ADF域的信息,JSessionId為
Weblogic cookie-name的默認值,而當再次訪問LWAP時,客戶端Cookie中的JSessionId的值被LWAP的域修改了,此時再次訪問
之前的ADF應用就會導致Session丟失。
網上可以找到關於這個問題的解決方案:
1,設置web應用的Cookie名稱,讓它們擁有不同的JSessionId
在LWAP和ADF的weblogic.xml文件添加如下屬性
<session-descriptor>
<session-param>
<param-name>CookieName</param-name>
<param-value>HADFCookie</param-value>
</session-param>
</session-descriptor>
2,一個應用使用IP來訪問,另外一個應用使用域名來訪問
一、現象:
在WebLogic中,有兩個不同域A(端口:9000)和B(端口:8000),應用CA在域A中,應用CB在域B中,進行如下操作:
1、先登錄應用CA,再登錄應用CB,然后,切換回應用CA,發現應用CA的Session丟失;
2、應用CA中有指向應用CB的鏈接,登錄應用CA,點擊指向應用CB的鏈接,應用CA的Session丟失;
二、原因:
因Cookie沖突導致Session丟失。
Cookie的覆蓋機制:如果一個新的cookie與一個已存在的cookie的NAME、Domain和Path屬性值均相同,則舊的cookie會被丟棄。(參考:http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_cookies)
WebLogic的Cookie相關配置:
屬性名 |
默認值 | 值 |
cookie-name | JSESSIONID | 如未設置,默認為“JSESSIONID” |
cookie-path | NULL | 如未設置,默認為“/” |
cookie-domain | NULL | 如未設置,默認為發放cookie的服務器的域 |
由於沒有在Weblogic.xml配置文件中對cookie的相關屬性值進行配置,因此應用CA和應用CB的cookie的Name、Domain和Path屬性值均為默認值,即Name為JSESSIONID,Path為“/”,Domain為服務器的IP地址,三個屬性值均相同,這就造成了應用CA的cookie與應用CB的cookie會互相覆蓋,從而導致相應應用的session丟失。
三、解決辦法:
在Weblogic.xml配置文件中增加Cookie的相應屬性值的配置:
方法1:設置各應用的cookie的Name屬性為不同值
方法2:設置各應用的cookie的Path屬性為不同值(cookie的Path屬性值需與context-root值保持一致,context-root若未在Weblogic.xml中指定則默認為部署的WAR包名或文件夾名,若同一Weblogic服務器不同域中的兩應用context-root相同,則此方法不可行)
附注:雖然問題是在WebLogic下的不同域部署應用進行互訪的情況下發現的,但是,從問題產生的原因來看,在同一個域中的不同應用的互訪,如果未做cookie相關屬性值的配置,也會出現cookie沖突的問題。
資料二:
1 關於WebLogic的Session丟失的問題
http://blog.csdn.net/DesignLife/article/details/2552186
2 tomcat向weblogic移植出現的問題系列 - session丟失問題
(其中一位網友回答不知是什么意思,要加什么文件)
http://netliving.iteye.com/blog/148485
3 java weblogic session 丟失
http://hi.baidu.com/leftstone/blog/item/3b34a4a19d4d0588471064f0.html
4 weblogic兩個domain中jsp相互調用session丟失解決方法
http://www.4ucode.com/Study/Topic/1159787
5 關於WebLogic的Session丟失的問題
http://hi.baidu.com/goylsf/blog/item/d2446677d71e070ab051b98d.html
6 weblogic通過代理插件weblogic.servlet.proxy.HttpProxyServlet跨域訪問導致session丟失問題的解決
http://ribbonchen.blog.163.com/blog/static/1183165052011074500877/
7 WebLogic如何設置session超時時間
http://tonyaction.blog.51cto.com/227462/201900
注意網上有很多的Webloigc不是最新的配置
位於WEB-INF/WebLogic.xml配置如下:
- <?xml version='1.0' encoding='utf-8'?>
- <weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
- http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
- http://www.bea.com/ns/weblogic/90
- http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">
- <container-descriptor>
- <prefer-web-inf-classes>true</prefer-web-inf-classes>
- </container-descriptor>
- <context-root>/</context-root>
- <session-descriptor>
- <!--WebLogic設置Session超時時間,在web.xml中去掉session超時設置 -->
- <!-- <timeout-secs>7200</timeout-secs> -->
- <cookie-name>JSESSIONID1</cookie-name>
- </session-descriptor>
- </weblogic-web-app>
一 WebLogic設置Session超時
1 web.xml
設置WEB應用程序描述符web.xml里的<session-timeout>元素。這個值以分鍾為
單位,並覆蓋weblogic.xml中的TimeoutSecs屬性
此例表示Session將在54分鍾后過期
當<session-timeout>設置為-2,表示將使用在weblogic.xml中設置的
TimeoutSecs這個屬性值。
當<session-timeout>設置為-1,表示Session將永不過期,而忽略在
weblogic.xml中設置的TimeoutSecs屬性值。
該屬性值可以通過console控制台來設置
在weblgoic的console中:xxDomain->Servers->xxServer->Protocols->HTTP 中有一個關於Post Timeout的配置,但這個參數一般使用默認值即可
一般是通過Services-->JDBC-->Connection Pools-->MyConnection(你所建立的連接池名)-->Configration-->Connections 里的Inactive Connection Timeout這個參數來設置的,默認的為0,表示連接時間無限長。你可以設一個時間值,連接超過這個時間值,它會把連接強制放回連接池- <Server AcceptBacklog="62" CompleteHTTPMessageTimeout="480"
- CompleteMessageTimeout="480" IdleC
- ListenAddress="" ListenPort="7001" Name="myserver"
- NativeIOEnabled="true" ReliableDeliveryPolicy="RMDefaultPolicy"
- ServerVersion="8.1.4.0">
是否IdleConnectionTimeout參數
2 weblogic.xml
設置WebLogic特有部署描述符weblogic.xml的<session-descriptor>元素的
TimeoutSecs屬性。這個值以秒為單位- <session-descriptor>
- <!--WebLogic設置Session超時時間,在web.xml中去掉session超時設置 -->
- <timeout-secs>7200</timeout-secs>
- </session-descriptor>
二 防止Webloigic下的iframe的Session失效
請在Weblogic.xml添加如下代碼
原來session在服務器端生成后分配的sessionID在客戶端的保存方式是個cookie,它的生命周期在瀏覽器關閉后就會結束,而這個cookie的名字如果不特別設置,weblogic會以默認的名稱“JSESSIONID”來設置這個cookie的名稱,我兩個應用的的session cookie名字都沒有設置,客戶端在第一次通過應用A請求代理轉發到應用B時,應用B返回的同名session cookie覆蓋了客戶端原本的應用A的session cookie,所以導致了應用A session的丟失。
解決方法是,在應用B的weblogic.xml中的session descriptor標記中添加session cookie的名稱設置,使其區別於A應用的session cookie名稱.其中的cookie-name可以重命名!解決在iframe中進行跨域訪問時session丟失的問題
附件有:weblogic-web-app.xsd資料三:
Tomcat改變JSESSIONID Set-Cookie的 Path
Set-Cookie: JSESSIONID=6941712CDVA075E14PF0C8DB15UF78E5; Path=/mywebapp
如果想將Path=/mywebapp 轉為 /
即:
Set-Cookie: JSESSIONID=16FB366B425C1EECD229BE1A395FD37C; Path=/
修改tomcat/conf/server.xml:- <Connector port="NN" maxHttpHeaderSize="8192"
- maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
- enableLookups="false" redirectPort="NN" acceptCount="100"
- connectionTimeout="20000" disableUploadTimeout="true"
- emptySessionPath="true"
- />
上面是針對tomcat6的,如果是tomcat7,emptySessionPath該屬性無效,
需要在context.xml加sessionCookiePath:
<Context ... sessionCookiePath="/" > ... </Context>
===================================================
http://hi.baidu.com/avill/item/fe0946da2ed382feca0c3940
一、現象:
在WebLogic中,有兩個不同域A(端口:9000)和B(端口:8000),應用CA在域A中,應用CB在域B中,進行如下操作:
1、先登錄應用CA,再登錄應用CB,然后,切換回應用CA,發現應用CA的Session丟失;
2、應用CA中有指向應用CB的鏈接,登錄應用CA,點擊指向應用CB的鏈接,應用CA的Session丟失;
二、原因:
因Cookie沖突導致Session丟失。
Cookie的覆蓋機制:如果一個新的cookie與一個已存在的cookie的NAME、Domain和Path屬性值均相同,則舊的cookie會被丟棄。(參考:http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_cookies)
WebLogic的Cookie相關配置:
屬性名
默認值值cookie-nameJSESSIONID如未設置,默認為“JSESSIONID”cookie-pathNULL如未設置,默認為“/”cookie-domainNULL如未設置,默認為發放cookie的服務器的域
由於沒有在Weblogic.xml配置文件中對cookie的相關屬性值進行配置,因此應用CA和應用CB的cookie的Name、 Domain和Path屬性值均為默認值,即Name為JSESSIONID,Path為“/”,Domain為服務器的IP地址,三個屬性值均相同,這就造成了應用CA的cookie與應用CB的cookie會互相覆蓋,從而導致相應應用的session丟失。
三、解決辦法:
在Weblogic.xml配置文件中增加Cookie的相應屬性值的配置:
方法1:設置各應用的cookie的Name屬性為不同值
方法2:設置各應用的cookie的Path屬性為不同值(cookie的Path屬性值需與context-root值保持一致,context-root若未在Weblogic.xml中指定則默認為部署的WAR包名或文件夾名,若同一Weblogic服務器不同域中的兩應用 context-root相同,則此方法不可行)
附注:雖然問題是在WebLogic下的不同域部署應用進行互訪的情況下發現的,但是,從問題產生的原因來看,在同一個域中的不同應用的互訪,如果未做cookie相關屬性值的配置,也會出現cookie沖突的問題。
======================================================
http://www.myexception.cn/web/902772.html
使用會話和會話持久性
以下部分描述如何設置和使用會話以及會話持久性:
HTTP 會話概述設置會話管理配置會話持久性用 URL 重寫替換 CookieServlet 會話跟蹤
HTTP 會話概述
通過會話跟蹤,您可以跟蹤用戶在多個自身無狀態的 servlet 或 HTML 頁面上的進度。會話被定義為特定時間段內來自同一個客戶端的一系列相關的瀏覽器請求。會話跟蹤將一系列瀏覽器請求聯結起來(可以將這些請求當作頁面來考慮),這些請求整體上可能具有一定的含義,例如購物車應用程序。
設置會話管理
默認情況下,WebLogic Server 設置為可以處理會話跟蹤。無需設置以下任何屬性即可使用會話跟蹤。但是,配置 WebLogic Server 管理會話的方式是調整應用程序以獲得最佳性能的關鍵部分。設置會話管理時,您需確定如下因素:
預期訪問 servlet 的用戶的數量每個會話的持續時間每個用戶的預期數據存儲量向 WebLogic Server 實例分配的堆大小
您還可以永久存儲來自 HTTP 會話的數據。請參閱配置會話持久性 。
HTTP 會話屬性
通過在 WebLogic 特定的部署描述符 weblogic.xml
中定義各種屬性,您可以配置 WebLogic Server 會話跟蹤。有關會話特性的完整列表,請參閱 session-descriptor 。
在以前的 WebLogic Server 版本中,引入了對 SessionID 格式的一個更改,以致某些負載平衡器喪失了保持會話粘滯性的能力。服務器啟動標志 -Dweblogic.servlet.useExtendedSessionFormat=true 保留了負載均衡應用程序保持會話粘滯性所需要的信息。如果激活了 URL 重寫功能,且啟動標志設置為真,則擴展會話 ID 格式將屬於 URL 的一部分。
會話超時
您可以指定 HTTP 會話過期的時間間隔。會話過期時,將放棄會話中存儲的所有數據。可以在 web.xml 或 weblogic.xml 中設置時間間隔:
在 WebLogic 特定的部署描述符weblogic.xml
中的 session-descriptor 元素中設置timeout-secs
參數值。該值以秒為單位進行設置。有關詳細信息,請參閱 session-descriptor 。在 J2EE 標准 Web 應用程序部署描述符web.xml
中設置 session-timeout 元素。
配置 WebLogic Server 會話 Cookie
客戶端瀏覽器支持 cookie 時,WebLogic Server 使用 cookie 進行會話管理。
默認情況下,WebLogic Server 用於跟蹤會話的 cookie 設置為暫態,其生存期不會超過會話期間。用戶退出瀏覽器時,cookie 丟失,會話結束。此行為主要用於會話,建議您以此方式使用會話。
您可以在 WebLogic 特定部署描述符 weblogic.xml
中配置 cookie 的 session-tracking 參數。會話及 cookie 相關參數的完整列表位於 session-descriptor 中。
配置生存期超過會話期間的應用程序 Cookie
要獲得生存期更長的客戶端用戶數據,您可以編寫自己的應用程序,通過 HTTP servlet API 在瀏覽器上創建和設置自己的 cookie。應用程序不應試圖使用與 HTTP 會話關聯的 cookie。您的應用程序可能會使用 cookie 以使用戶從特定計算機自動登錄,這樣,您需要設置新的 cookie 以持續更長時間。請記住,只能從此特定客戶端計算機發送 cookie。如果用戶必須從多個位置進行訪問,您的應用程序應該在服務器上存儲數據。
您不能直接將瀏覽器 cookie 的期限與會話時間長度關聯起來。否則,如果 cookie 在其關聯會話之前過期,則會話會變得孤立。而如果會話在其關聯 cookie 之前過期,則 servlet 無法找到該會話。這種情況下,當調用request.getSession(true)
方法時,將自動分配一個新會話。
可以使用 weblogic.xml
部署描述符的會話描述符中的 cookie-max-age-secs
元素設置 cookie 的最大生命周期。請參閱 cookie-max-age-secs 。
退出和結束會話
用戶身份驗證信息既存儲於用戶會話數據中,也存儲於 Web 應用程序所定位的服務器或虛擬主機的上下文中。通常用於使用戶退出的 session.invalidate()
方法僅使用戶的當前會話失效,用戶身份驗證信息仍有效,且存儲於服務器或虛擬主機的上下文中。而如果服務器或虛擬主機僅承載一個 Web 應用程序,則 session.invalidate()
方法實際上會使用戶退出。
針對多個 Web 應用程序使用身份驗證時,有多種 Java 方法和策略可以使用。有關詳細信息,請參閱退出和結束會話 。
使 Web 應用程序共享同一個會話
默認情況下,Web 應用程序不共享同一個會話。如果您希望 Web 應用程序共享同一個會話,您可以在 weblogic-application.xml
部署描述符中配置應用程序級別上的會話描述符。要使 Web 應用程序共享同一個會話,請將weblogic-application.xml
部署描述符中會話描述符中的 sharing-enabled
特性設置為 true
。請參閱 session-descriptor 中的“sharing-enabled”。
應用程序級別上指定的會話描述符配置將替代在 Web 應用程序級別上為應用程序中所有 Web 應用程序指定的任何會話部署描述符配置。如果您在 Web 應用程序級別上將 sharing-enabled
特性設置為真,則將忽略該設置。
如果您在 weblogic-application.xml
部署描述符中指定會話描述符,並將 sharing-enabled
特性設置為 true
,則應用程序中的所有 Web 應用程序將自動使用同一個會話實例啟動,如以下示例所示:
<?xml version="1.0" encoding="ISO-8859-1"?>
<weblogic-application xmlns="http://www.bea.com/ns/weblogic/90";;> ... <session-descriptor> <persistent-store-type>memory</persistent-store-type> <sharing-enabled>true</sharing-enabled> ... </session-descriptor> ... </weblogic-application>
配置會話持久性
使用會話持久性永久存儲 HTTP 會話對象中的數據,以便支持 WebLogic Server 群集之間的故障轉移和負載平衡,應用程序存儲 HTTP 會話對象中的數據時,數據必須是可序列化的。
會話持久性有五種不同的實現方法:
內存(單個服務器,非復制)文件系統持久性JDBC 持久性基於 Cookie 的會話持久性內存中復制(跨群集)
此處僅討論前四項;內存中復制將在使用 WebLogic Server 群集 中的 HTTP 會話狀態復制 中討論。
基於文件、JDBC 和 cookie 的會話持久性與內存(單服務器,非填充)會話持久性具有某些共同的屬性。每個持久性方法具有其自己的一組可配置參數,如以下部分所討論。這些參數是 weblogic.xml 部署描述符文件中 session-descriptor 元素的子元素。
不同類型的會話持久性的共有特性
此部分描述基於文件的持久性和基於 JDBC 的持久性共用的參數。通過在 weblogic.xml 部署描述符文件中的 session-descriptor 元素中定義下列參數,您可以配置內存中保留的會話數量。以下參數僅適用於您使用會話持久性時:
cache-size
注意: | 基於 JDBC 和基於文件的會話使用 cache-size 的目的僅僅是維護內存中出現的緩存。它不適用於其他持久性類型。 |
invalidation-interval-secs
使用基於內存的單服務器非復制持久性存儲
使用基於內存的存儲時,所有會話信息都存儲在內存中,當您停止並重新啟動 WebLogic Server 時,這些信息都會丟失。要使用基於內存的單服務器非復制持久性存儲,請將 weblogic.xml 部署描述符文件中的 session-descriptor 元素中 persistent-store-type
參數設置為 memory。請參閱 persistent-store-type 。
注意: | 如果運行 WebLogic Server 時沒有分配足夠的堆大小,服務器將由於高額負載而導致內存不足。 |
使用基於文件的持久性存儲
要為會話配置基於文件的持久性存儲,請執行下列操作:
在部署描述符文件weblogic.xml
中,將 weblogic.xml 部署描述符文件中 session-descriptor 元素中的persistent-store-type
參數設置為file
。請參閱 persistent-store-type 。設置 WebLogic Server 存儲會話的目錄。請參閱 persistent-store-dir 。
注意: | 必須自行創建此目錄,並確保已為該目錄分配適當的訪問權限。 |
使用數據庫進行持久性 存儲(JDBC 持久性)
JDBC 持久性通過使用專為此目的而提供的 Schema 將會話數據存儲在數據庫表中。可以使用您有 JDBC 驅動程序的任何數據庫。通過使用連接緩沖池配置數據庫訪問。
由於 WebLogic Server 在使用 JDBC 會話持久性時會使用系統時間確定會話生命周期,所以您必須確保其上服務器是在同一個群集中運行的所有計算機上的系統時鍾。
配置基於 JDBC 的持久性存儲
要為會話配置基於 JDBC 的持久性存儲,請執行下列步驟:
將 weblogic.xml 部署描述符文件中 session-descriptor 元素中的persistent-store-type
參數設置為jdbc
。請參閱 persistent-store-type 。使用 weblogic.xml 部署描述符文件中 session-descriptor 元素中的persistent-store-pool
參數設置要用於持久性存儲的 JDBC 連接緩沖池。使用 WebLogic Server 管理控制台中定義的連接緩沖池的名稱。請參閱 persistent-store-pool 。為基於 JDBC 的持久性設置一個名為wl_servlet_sessions
的數據庫表。連接數據庫的連接緩沖池需要具有該表的讀/寫訪問權。
注意: | 如果數據庫沒有自動創建索引,請在 wl_id 和 wl_context_path 上創建。某些數據庫會自動為主關鍵字創建索引。 |
按如下說明設置列名稱和數據類型。
wl_id
|
VARCHAR2(100) .
主關鍵字必須按如下設置: wl_id + wl_context_path.
|
wl_context_path
|
VARCHAR2(100) 。
此列用作主關鍵字的一部分。(請參閱
wl_id 列描述。)
|
wl_is_new
|
CHAR(1)
|
wl_create_time
|
NUMBER(20)
|
wl_is_valid
|
CHAR(1)
|
wl_session_values
|
LONG RAW
|
wl_access_time
|
NUMBER(20)
|
wl_max_inactive_interval
|
Integer 。如果兩個客戶端請求之間的時間超過此秒數,則會話將失效。負時間值表明會話永不超時。
|
如果您使用的是 Oracle DBMS,請使用下面的 SQL 語句創建 wl_servlet_sessions
表。請修改該 SQL 語句以用於您的 DBMS。
create table wl_servlet_sessions ( wl_id VARCHAR2(100) NOT NULL, wl_context_path VARCHAR2(100) NOT NULL, wl_is_new CHAR(1), wl_create_time NUMBER(20), wl_is_valid CHAR(1), wl_session_values LONG RAW, wl_access_time NUMBER(20), wl_max_inactive_interval INTEGER, PRIMARY KEY (wl_id, wl_context_path) );
注意: | 您可以使用 jdbc-connection-timeout-secs 參數配置 JDBC 會話持久性等待連接緩沖池中的 JDBC 連接的最大持續時間,超過該時間將無法加載會話數據。有關詳細信息,請參閱 jdbc-connection-timeout-secs 。 |
如果您使用的是 SqlServer2000,請使用下面的 SQL 語句創建 wl_servlet_sessions
表。請修改該 SQL 語句以用於您的 DBMS。
create table wl_servlet_sessions ( wl_id VARCHAR2(100) NOT NULL, wl_context_path VARCHAR2(100) NOT NULL, wl_is_new VARCHAR(1), wl_create_time DECIMAL, wl_is_valid VARCHAR(1), wl_session_values IMAGE, wl_access_time DECIMAL, wl_max_inactive_interval INTEGER, PRIMARY KEY (wl_id, wl_context_path) );
如果您使用的是 Pointbase,Pointbase 會轉換該 SQL。例如,Pointbase 會按照如下方式轉換清單 8-1 中提供的 SQL。
SQL> describe wl_servlet_sessions;
WL_SERVLET_SESSIONS
WL_ID VARCHAR(100) NULLABLE: NO
WL_CONTEXT_PATH VARCHAR(100) NULLABLE: NO
WL_IS_NEW CHARACTER(1) NULLABLE: YES
WL_CREATE_TIME DECIMAL(20) NULLABLE: YES
WL_IS_VALID CHARACTER(1) NULLABLE: YES
WL_SESSION_VALUES BLOB(65535) NULLABLE: YES
WL_ACCESS_TIME DECIMAL(20) NULLABLE: YES
WL_MAX_INACTIVE_INTERVAL INTEGER(10) NULLABLE: YES
Primary Key: WL_CONTEXT_PATH
Primary Key: WL_ID
如果您使用的是 DB2,請使用下面的 SQL 語句創建 wl_servlet_sessions
表。請修改該 SQL 語句以用於您的 DBMS。
CREATE TABLE WL_SERVLET_SESSIONS ( WL_ID VARCHAR(100) not null, WL_CONTEXT_PATH VARCHAR(100) not null, WL_IS_NEW SMALLINT, WL_CREATE_TIME DECIMAL(16), WL_IS_VALID SMALLINT, wl_session_values BLOB(10M) NOT LOGGED, WL_ACCESS_TIME DECIMAL(16), WL_MAX_INACTIVE_INTERVAL INTEGER, PRIMARY KEY (WL_ID,WL_CONTEXT_PATH)
);
如果您使用的是 Sybase,請使用下面的 SQL 語句創建 wl_servlet_sessions
表。請修改該 SQL 語句以用於您的 DBMS。
create table WL_SERVLET_SESSIONS ( WL_ID varchar(100) not null , WL_CONTEXT_PATH varchar(100) not null , WL_IS_NEW smallint null , WL_CREATE_TIME decimal(16,0) null , WL_IS_VALID smallint null , WL_SESSION_VALUES image null , WL_ACCESS_TIME decimal(16,0) null , WL_MAX_INACTIVE_INTERVAL int null , ) go alter table WL_SERVLET_SESSIONS add PRIMARY KEY CLUSTERED (WL_ID, WL_CONTEXT_PATH) go
JDBC 會話持久性的緩存與數據庫更新
如果請求是只讀的,WebLogic Server 不會向磁盤中寫入 HTTP 會話狀態,這表明該請求不修改 HTTP 會話。如果訪問該會話,則僅更新數據庫中的 wl_access_time 列。
對於非只讀請求,每次 HTTP 請求后,Web 應用程序容器都會在數據庫中更新會話狀態的變化。因此,群集中的任意服務器均可處理一旦發生故障轉移時的請求,並從數據庫中檢索最新會話狀態。
為防止多個數據庫查詢,WebLogic Server 將緩存最近使用的會話。每次請求時,並不從數據庫中刷新最近使用的會話。緩存中會話的數量由 WebLogic Server 特定的部署描述符 weblogic.xml 中的 cache-size 參數控制。請參閱 cache-size 。
使用基於 Cookie 的會話持久性
基於 Cookie 的會話持久性提供了會話持久性的無狀態解決方案,方法是將所有會話數據存儲在用戶瀏覽器的 cookie 中。不需要在會話中存儲大量數據時,基於 Cookie 的會話持久性最適用。由於不需要群集故障轉移邏輯,所以基於 Cookie 的會話持久性能夠簡化 WebLogic Server 安裝的管理。由於會話存儲於瀏覽器中,而不存儲於服務器上,所以啟動和停止 WebLogic Server 時不會丟失會話。
基於 cookie 的會話持久性具有某些限制:
只能存儲會話中的字符串特性。如果您存儲會話中的任何其他類型的對象,則會引發IllegalArgument
異常。不能刷新 HTTP 響應(因為必須先將 cookie 寫入頭數據中,然后才可以提交響應 )。如果響應內容的長度超出緩沖大小,則自動刷新響應,不更新 cookie 中的會話數據。(緩沖大小默認為 8192 字節。)您可以使用javax.servlet.ServletResponse.setBufferSize()
方法更改緩沖區大小。只能使用基本(基於瀏覽器)身份驗證。會話數據以明文方式發送至瀏覽器。必須對用戶瀏覽器進行配置以接受 cookie。使用基於 cookie 的會話持久性時,字符串內不能使用逗號,否則會引發異常。
要設置基於 cookie 的會話持久性,請執行下列步驟:
將 weblogic.xml 部署描述符文件中 session-descriptor 元素中的persistent-store-type
參數設置為cookie
。請參閱 persistent-store-type 。或者,使用persistent-store-cookie-name
元素為 cookie 設置一個名稱。默認值為WLCOOKIE
。請參閱 persistent-store-cookie-name 。
用 URL 重寫 替換 Cookie
在某些情況下,瀏覽器或無線設備可能不接受 cookie,因此無法使用 cookie 進行會話跟蹤。對於這種情況,URL 重寫是一個解決方案,當 WebLogic Server 檢測到瀏覽器不接受 cookie 時,會自動替換為 URL 重寫。URL 重寫包括將會話 ID 編碼到 servlet 傳回瀏覽器的那些網頁的超鏈接中。當用戶隨后單擊這些鏈接時,WebLogic Server 將從 URL 地址中提取 ID,並在 servlet 調用 getSession()
方法時查找相應的 HttpSession
。
在 WebLogic 特定的部署描述符 weblogic.xml
中的 session-descriptor 元素下,設置 url-rewriting-enabled
參數,從而啟用 WebLogic Server 中的 URL 重寫。此特性的默認值是 true
。請參閱 url-rewriting-enabled 。
URL 重寫的編碼准則
下面是支持 URL 重寫的一般准則。
避免直接向輸出流中寫入 URL,如下顯示:
out.println("<a href=\"/myshop/catalog.jsp\">catalog</a>");
而要使用 HttpServletResponse.encodeURL()
方法,例如:
out.println("<a href=\" + response.encodeURL("myshop/catalog.jsp") + "\">catalog</a>");
調用 encodeURL()
方法可以確定 URL 是否需要重寫。如果確實需要重寫,WebLogic Server 將重寫 URL,即,在會話 ID 前添加一個分號,然后將其追加到 URL 后面。
除作為 WebLogic Server 響應而返回的 URL 外,還會對發送重定向的 URL 進行編碼。例如:
if (session.isNew()) response.sendRedirect (response.encodeRedirectUrl(welcomeURL));
新建會話時,即使瀏覽器確實接受 cookie,WebLogic Server 也將使用 URL 重寫,因為在初次訪問會話時,服務器無法判斷瀏覽器是否接受 cookie。
當使用插件(Apache、NSAPI、ISAPI、HttpClusterServlet
或 HttpProxyServlet
)時,如果在使用response.sendRedirect(url)
或 response.encodeRedirectURL(url)
的后端服務器上使用 URL 重寫,則在以下條件下 PathTrim
和 PathPrepend
參數將被應用於該 URL:如果 PathPrepend
為空或已經應用了PathPrepend
,那么只將 PathTrim
應用於 URL。
通過檢查從HttpServletRequest.isRequestedSessionIdFromCookie()
方法返回的 Boolean,servlet 可以判斷給定的會話 ID 是否是從 cookie 中收到的。您的應用程序可能會相應響應,或僅依賴於 WebLogic Server 的 URL 重寫。
注意: | CISCO 本地定向器負載均衡器要求 URL 重寫中使用問號“?”分隔符。由於 WLS URL 重寫機制使用分號“;”作為分隔符,因此 URL 重寫與該負載均衡器不兼容。 |
URL 重寫和無線訪問協議 (WAP)
如果您正在編寫 WAP 應用程序,您必須使用 URL 重寫,因為 WAP 協議不支持 cookie。另外,某些 WAP 設備對 URL 長度有 128 位字符的限制(其中包括特性),這限制了使用 URL 重寫可以傳輸的數據量。為了給各個特性預留較多空間,可以限制 WebLogic Server 隨機生成的會話 ID 的大小。
特別是,如果要使用 WAPEnabled
特性,請通過單擊“服務器” “協議”
HTTP
“高級選項”使用管理控制台。
WAPEnabled
特性將會話 ID 的大小限制在 52 位字符內,且不允許使用特殊字符,例如“!”和“#”。還可以使用 weblogic.xml 的 IDLength 參數進一步限制會話 ID 的大小。有關其他詳細信息,請參閱 id-length 。
Servlet 會話跟蹤
通過會話跟蹤,可以跟蹤用戶在多個自身無狀態的 servlet 或 HTML 頁面上的進度。 會話被定義為特定時間段內來自同一個客戶端的一系列相關的瀏覽器請求。會話跟蹤將一系列瀏覽器請求聯結起來(可以將這些請求當作頁面來考慮),這些請求整體上可能具有一定的含義,例如購物車應用程序。
以下部分討論 HTTP servlet 會話跟蹤的各個方面:
會話跟蹤的歷史通過 HttpSession 對象跟蹤會話會話生命周期會話跟蹤的工作方式檢測會話的開始設置和獲取會話名/值特性退出和結束會話配置會話跟蹤用 URL 重寫替換 CookieURL 重寫和無線訪問協議 (WAP)使會話持久
會話跟蹤的歷史
在會話跟蹤這個概念成熟之前,開發人員嘗試將狀態構建在頁面中,他們將信息填充在頁面的隱藏字段中,或使用一長串追加字符將用戶選項嵌入鏈接中使用的 URL 中。在大多數搜索引擎站點上,您可以看到很好的這樣的示例,它們多數仍依賴於 CGI。這些站點通過在 URL 中 HTTP 保留字符 ?
后追加 URL 參數 name
=value
對來跟蹤用戶選項。這種方法會產生非常長的 URL,CGI 腳本必須仔細地對其進行解析和管理。這種方法的問題在於,無法在會話之間傳遞這些信息。一旦失去對 URL 的控制,即一旦用戶離開某個頁面,用戶信息將永久丟失。
后來,Netscape 引入了瀏覽器 cookie, 因此您能夠為每個服務器存儲關於客戶端的用戶相關信息。但是,某些瀏覽器仍無法完全支持 cookie,而且某些用戶喜歡關閉瀏覽器中的 cookie 選項。另外一個需要考慮的因素是,多數瀏覽器限制了 cookie 中可存儲的數據量。
與 CGI 方法不同,HTTP servlet 規范定義了一個解決方案,除在服務器上存儲單個會話外,還允許服務器存儲用戶詳細信息,避免了由代碼處理會話跟蹤的復雜性。servlet 可以使用 HttpSession
對象跟蹤用戶在單個會話期間的輸入,並在多個 servlet 之間共享會話詳細信息。使用 WebLogic 服務提供的多種方法,可以持久保存會話數據。
通過 HttpSession 對象跟蹤會話
根據 WebLogic Server 實現並支持的 Java Servlet API,每個 servlet 都可以使用其 HttpSession
對象訪問服務器端會話。通過使用 HttpServletRequest
對象及 request
變量,您可以在 servlet 的 service()
方法中訪問 HttpSession
對象,如下所示:
HttpSession session = request.getSession(true);
當使用參數 true
調用 request.getSession(true)
方法時,如果該客戶端尚不存在 HttpSession
對象,則將創建該對象。在會話生命周期內,會話對象生存於 WebLogic Server 上,並且會累計與該客戶端相關的信息。servlet 會按照需要在會話對象中添加或刪除信息。會話與特定的客戶端關聯。每次客戶端訪問 servlet 時,如果調用 getSession()
方法,便會檢索同一個關聯的 HttpSession
對象。
有關 HttpSession
所支持方法的詳細信息,請參閱 HttpServlet API 。
在下面的示例中,service()
方法將計算用戶在會話期間請求 servlet 的次數。
public void service(HttpServletRequest request, HttpServletResponse, response) throws IOException { // 獲取會話和計數器參數特性 HttpSession session = request.getSession (true); Integer ival = (Integer) session.getAttribute("simplesession.counter"); if (ival == null) // 初始化計數器 ival = new Integer (1); else // 增加計數器 ival = new Integer (ival.intValue () + 1); // 在會話中設置新特性值 session.setAttribute("simplesession.counter", ival); // 輸出 HTML 頁 out.print("<HTML><body>"); out.print("<center> You have hit this page "); out.print(ival + " times!"); out.print("</body></html>"); }
會話生命周期
會話將跟蹤用戶在單個事務中在一系列頁面上所進行的選擇。單個事務可能包含多個任務,例如搜索商品,將其添加到購物車中,然后處理付款。會話是暫態的,發生以下情況時,會話生命周期將結束:
用戶離開您的站點,且用戶瀏覽器不接受 cookie。用戶退出瀏覽器。會話由於不活動而超時。會話已完成,servlet 使會話失效。用戶退出,servlet 使用戶失效。
要獲得更多長期存儲的持久數據,您的 servlet 應該使用 JDBC 或 EJB 向數據庫中寫入詳細信息,並使用具有較長生命周期的 cookie 和/或用戶名和密碼將客戶端與該數據關聯起來。盡管本文中聲明會話在內部使用 cookie 和持久性,但您不應將會話用作存儲用戶數據的一般機制。
會話跟蹤的工作方式
WebLogic Server 如何獲知與每個客戶端關聯的會話?當在 servlet 中創建 HttpSession
時,它將與一個唯一的 ID 關聯。瀏覽器必須在其請求中提供此會話 ID,以便服務器能夠再次找到該會話數據。服務器嘗試通過在客戶端設置 cookie 來存儲此 ID。一旦設置 cookie,瀏覽器每次向服務器發出請求時,請求中將包括包含該 ID 的 cookie。當調用getSession()
方法時,服務器自動解析該 cookie 並提供會話數據。
如果客戶端不接受 cookie,唯一的替代方法是,將該 ID 編碼到傳回客戶端的頁面的 URL 鏈接中。出於此原因,在 servlet 響應中包括 URL 時,應該始終使用 encodeURL()
方法。WebLogic Server 檢測瀏覽器是否接受 cookie,並不一定會編碼 URL。當您調用 getSession()
方法時,WebLogic 會自動從編碼的 URL 中解析會話 ID,並檢索正確的會話數據。無論使用什么過程跟蹤會話,使用 encodeURL()
方法都可以確保不干擾 servlet 代碼。有關詳細信息,請參閱用 URL 重寫替換 Cookie 。
檢測 會話的開始
使用 getSession(true)
方法獲取會話后,可以判斷該會話是否是剛才通過調用 HttpSession.isNew()
方法而創建的。如果該方法返回 true
,則客戶端尚不具有有效會話,此時,它並不知道新會話已經創建。只有當服務器發布回復之后,該客戶端才知道新會話的存在。
將應用程序設計為以符合業務邏輯的方式包含新會話或現有會話。例如,如果確定會話尚未啟動,應用程序可以將客戶端 URL 重定向至登錄/密碼頁面,如下面的代碼示例所示:
HttpSession session = request.getSession(true); if (session.isNew()) { response.sendRedirect(welcomeURL); }
登錄頁面上提供一個選擇:登錄系統或創建新帳戶。您還可以使用 J2EE 標准 Web 應用程序部署描述符 web.xml 的 login-config 元素指定 Web 應用程序中的登錄頁面。
設置和獲取會話名/值特性
可以使用 name=value
對存儲 HttpSession
對象中的數據。會話中存儲的數據僅能通過會話提供。要在會話中存儲數據,請使用 HttpSession
接口的以下方法:
getAttribute() getAttributeNames() setAttribute() removeAttribute()
下面的代碼段顯示如何獲取全部的現有 name=value
對:
Enumeration sessionNames = session.getAttributeNames(); String sessionName = null; Object sessionValue = null; while (sessionNames.hasMoreElements()) { sessionName = (String)sessionNames.nextElement(); sessionValue = session.getAttribute(sessionName); System.out.println("Session name is " + sessionName + ", value is " + sessionValue); }
要添加或覆蓋已命名的特性,請使用 setAttribute()
方法。要一起刪除已命名的特性,請使用 removeAttribute()
方法。
注意: | 您可以添加 Object 的任意 Java 子項作為會話特性,並將一個名稱與其關聯。但是,如果您使用的是會話持久性,您的特性 value 對象必須實現 java.io.Serializable 。 |
退出和結束會 話
如果您的應用程序處理的信息比較敏感,請考慮提供退出會話的功能。在使用購物車和 Internet 電子郵件帳戶時,這是一個常用功能。當同一瀏覽器返回服務時,用戶必須登錄回系統。
針對單個 Web 應用程序使用 session.invalidate()
用戶身份驗證信息既存儲於用戶會話數據中,也存儲於 Web 應用程序所定位的服務器或虛擬主機的上下文中。通常用於使用戶退出的 session.invalidate()
方法僅使用戶的當前會話失效,用戶身份驗證信息仍有效,且存儲於服務器或虛擬主機的上下文中。而如果服務器或虛擬主機僅承載一個 Web 應用程序,則 session.invalidate()
方法實際上會使用戶退出。
在調用 session.invalidate()
之后,不要引用無效的會話。如果引用,則將引發 IllegalStateException
。下次用戶從同一個瀏覽器訪問您的 servlet 時,會話數據將丟失,調用 getSession(true)
方法時候將創建新會話。此時,您可以再次將用戶發送至登錄頁面。
針對多個應用程序實現單一登錄
如果服務器或虛擬主機是多個 Web 應用程序的目標,需要采用其他方式使用戶退出所有 Web 應用程序。由於 Servlet 規范不提供用戶退出所有 Web 應用程序的 API,因此提供以下方法。
weblogic.servlet.security.ServletAuthentication.logout()
weblogic.servlet.security.ServletAuthentication.invalidateAll()
weblogic.servlet.security.ServletAuthentication.killCookie()
避免 Web 應用程序的單一登錄
如果您不希望某 Web 應用程序參與單一登錄,請為該 Web 應用程序定義另外一個 cookie 名稱。有關詳細信息,請參閱配置 WebLogic Server 會話 Cookie 。
配置會話跟蹤
WebLogic Server 提供多種可配置的特性,它們將確定 WebLogic Server 如何處理會話跟蹤。有關配置這些會話跟蹤特性的詳細信息,請參閱 session-descriptor 。
使用 URL 重寫替代 Cookie
在某些情況下,瀏覽器可能不接受 cookie,這表明無法通過 cookie 跟蹤會話。對於這種情況,URL 重寫是一個解決方法,當 WebLogic Server 檢測到瀏覽器不接受 cookie 時,會自動替換為 URL 重寫。URL 重寫包括將會話 ID 編碼到 servlet 傳回瀏覽器的那些網頁的超鏈接中。當用戶隨后單擊這些鏈接時,WebLogic Server 將從該 URL 中提取 ID,並查找相應的 HttpSession
。然后可以使用 getSession()
方法訪問會話數據。
要在 WebLogic Server 中啟用 URL 重寫功能,請在 WebLogic Server 特定的部署描述符 weblogic.xml 中的 session-descriptor 元素中,將 URL-rewriting-enabled
參數設置為 true。請參閱 url-rewriting-enabled 。
為確保您的代碼能夠正確處理 URL 以支持 URL 重寫功能,請考慮下列准則:
應避免直接向輸出流中寫入 URL,如以下所示:
out.println("<a href=\"/myshop/catalog.jsp\">catalog</a>");
而使用 HttpServletResponse.encodeURL()
方法。例如:
out.println("<a href=\"" + response.encodeURL("myshop/catalog.jsp") + "\">catalog</a>");
調用encodeURL()
方法確定 URL 是否需要重寫,如果需要,則通過在 URL 中包含會話 ID 重寫該 URL。對發送重定向的 URL 以及作為響應而返回至 WebLogic Server 的 URL 進行編碼。例如:
if (session.isNew()) response.sendRedirect (response.encodeRedirectUrl(welcomeURL));
新建會話時,即使瀏覽器接受 cookie,WebLogic Server 也將使用 URL 重寫功能,因為在初次訪問會話時,服務器無法確定瀏覽器是否接受 cookie。
通過檢查 HttpServletRequest.isRequestedSessionIdFromCookie()
方法返回的 Boolean,servlet 可以確定給定會話是否是從 cookie 中返回的。您的應用程序可能會相應響應,或僅依賴於 WebLogic Server 的 URL 重寫。
注意: | CISCO 本地定向器負載均衡器要求 URL 重寫中使用問號“?”分隔符。由於 W |