session,cookie,丢失,不能保存;apache,weblogic
....
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 |