<script type="text/javascript"></script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script> |
<script type="text/javascript"></script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script> |
apache + resin的多机负载分布和多个webapp统一认证的实现方案, 期间设计多个webapp统一认证的实现方案时, 发现resin下通过cookie来传递jsessionid和通过url重写将jsessionid放url中传递, 会有细微的差异.
在servlet规范中,HttpServletSession的获取时通过调用request.getSession(boolean createnew)方法来实现,其实现机制可以简单的理解为: 存在一个大的hashMap结构,key就是jsessionid,而valule是HttpservletSession对象。 request.getSession(boolean createnew)方法通过jsessionid来获取对应的HttpservletSession,如果不存在并且参数createnew= true,则创建一个新的HttpservletSession对象,并设置jsessionid=session.getId() ,保存到hashMap结构中。以后再传递这个jsessionid. (详细的过程比较复杂,各家的实现也不尽相同,但大体的实现原理是如此。)
关注以下几点:
一). 获取jsessionid
jsessionid的传递可以是以下途径
1. 放在cookie中
Cookie: JSESSIONID=abcrmF3Gx-5Z-hhkgHfzr
2. 以参数形式放在url
http://10.3.2.35:11280/wmail/welcome.action?jsessionid=abcQNqiT4C01rg-necLBr
3. 用form表单传递,通常是用隐藏域
<input type="hidden" name="jsessionid" value="abcQNqiT4C01rg-necLBr"/>
4. url重写
http://10.3.2.35:11280/jid=abcQNqiT4C01rg-necLBr/wmail/welcome.action
或者
http://10.3.2.35:11280/wmail/welcome.action;jsessionid=abcQNqiT4C01rg-necLBr
如果当前还没有jsessionid则当然就无法获取,通常用户第一次访问或者登录前就是这种情况.
可以通过request.getRequestedSessionId() 方法来获取本次http 请求的jsessonid值。
二)获取到的HttpServletSession对象
如果HttpServletSession对象是已经存在的,则
1. session.isNew()=false
2. request.getRequestedSessionId() == jsessionid == session.getId()
如果HttpServletSession对象是调用request.getSession(true) (简写的request.getSession()方法等同于request.getSession(true) )时新创建的,则有以下特征:
1. session.isNew()=true
2. 以后传递的jsessionid=session.getId()
注意这里,如果request.getRequestedSessionId() 是空值,情况比较简单,以后传递jsessionid=session.getId()就是了。
但是如果request.getRequestedSessionId() 不是空值,通过这个值没有获取到已经存在的session对象,而是返回了一个新的session对象,这个时候新的session.getId()和原有的request.getRequestedSessionId() 关系如何呢?下面详细阐述这种情况。
三) request.getRequestedSessionId() 不是空值时,新的session.getId() = ?
1). 测试代码如下:
HttpServletRequest request = ServletActionContext.getRequest();
String jid1 = request.getRequestedSessionId();
HttpSession session = request.getSession(true);
String jid2 = request.getRequestedSessionId();
logger.info("get HttpSession , isNew()=" + session.isNew()
+ " getId()=" + session.getId()
+ " and jid1=" + jid1
+ " and jid2=" + jid2);
其中jid1和jid2分别是调用request.getSession(true)方法前后的request.getRequestedSessionId()值。
在resin中运行以上代码,测试request.getRequestedSessionId() 不是空值而对应jsessionid的session不存在的情况。
2). 通过cookie来传递jsessionid的情况,测试结果如下:
get HttpSession, isNew()=true getId()=abcqIgQroQ2Ov9lGYcYAr and jid1=abcqIgQroQ2Ov9lGYcYAr and jid2=abcqIgQroQ2Ov9lGYcYAr
get HttpSession, isNew()=true getId()=abcPQ3mpxKz8H-4UMdYAr and jid1=abcPQ3mpxKz8H-4UMdYAr and jid2=abcPQ3mpxKz8H-4UMdYAr
get HttpSession, isNew()=true getId()=abcdeE3iDy_bI536tLYAr and jid1=abcdeE3iDy_bI536tLYAr and jid2=abcdeE3iDy_bI536tLYAr
可以发现以下规律:
1. isNew()=true
2. session.getId() == jid1 == jid2
即新创建的session会使用传递过来的jsessionid值,即使这个jsessionid值根本没有对应的session存在
3) 通过url重写,将jsessionid放url中传递, 测试结果如下:
get HttpSession, isNew()=true getId()=abccw1zEC_RcN43qHMYAr and jid1=abcdUdTfKuLbge8h_LYAr and jid2=abcdUdTfKuLbge8h_LYAr
http://10.3.2.35:11280/jid=abccw1zEC_RcN43qHMYAr/uab/contactList.action
get HttpSession, isNew()=true getId()=abcFK7yOB1irgaYqgNYAr and jid1=abci-HpMPJU3egCB7MYAr and jid2=abci-HpMPJU3egCB7MYAr
http://10.3.2.35:11280/jid=abcFK7yOB1irgaYqgNYAr/uab/contactList.action
(后面的http地址为页面跳转完成后显示在浏览器地址框中的页面url)
可以发现以下规律:
1. isNew()=true
2. jid1 == jid2
request.getRequestedSessionId()值在request.getSession(true)方法调用前后无变化
3. session.getId() != jid1
即新创建的session不使用传递过来的jsessionid值,而是采用新值
4. 跳转完成后的http地址中,使用的是session.getId(), 而不是原来通过url重写传递过来的jsessionid
此时新的jsessionid覆盖了旧有的jsessionid.
4) 总结
在resin的实现中, 通过cookie来传递jsessionid的情况和通过url重写将jsessionid放url中传递, 会有细微的差异.
以上测试的resin版本为3.0.26, 稍后有时间考虑测试其他版本和tomcat.
这个差异直接影响到跨webapp的多个webapp直接相互传递jsessionid的方式, 通过cookie传递jsessionid可以做到多个webapp之间在页面跳转时始终是一个相同的jsessionid,这种各个应用都可以方便的获取到自己的HttpServletSession对象. 但是如果是通过url重写,则破坏了jsessonid的一致性, 逼迫各个webapp之间跳转时必须用其他额外的方法来保证传递给对方的jsessionid的准确性,因为此时每个webapp的jsessionid 都不一样了,必须记住其他每个webapp的jsessionid,造成跨webapp的页面跳转极其复杂,难于接受.
<script type="text/javascript"></script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>
分享到:
相关推荐
如果客户端禁用了Cookie,服务器可以通过URL重写或表单隐藏字段的方式来传递Session ID。URL重写是在URL路径或查询字符串中附加Session ID,而表单隐藏字段则是在HTML表单中添加一个隐藏的输入元素,用于在表单提交...
综上所述,JavaWeb中的Session技术是实现用户自动登录的核心,它通过在服务器端存储用户信息并在客户端通过Cookie传递Session ID来保持用户状态。正确地配置和管理Session,能够为用户提供流畅的登录体验,同时也...
总结来说,Tomcat中的Session是通过Session ID(JSESSIONID)作为标识,结合Cookie在客户端和服务器之间传递,实现对用户会话状态的跟踪。了解这些原理对于优化Web应用性能、处理会话管理问题以及确保用户安全性至关...
- **会话跟踪**:除了Cookie,还可以使用URL重写或者隐藏表单字段来传递Session ID,但Cookie是最常见的方法。 - **安全性**:需要注意Session劫持和Session固定攻击,可以通过使用HTTPS、定期更换Session ID、...
为了克服这一限制,引入了Session机制来维持会话状态。 2. **Cookie与Session的区别**:Cookie是在客户端存储信息的一种方式,而Session则是在服务器端存储用户会话信息的方式。两者都可用于跟踪用户状态,但Cookie...
在探讨“IFrame中Session丢失的解决办法”这一主题时,我们首先需要理解Session与IFrame的基本概念及其在Web开发中的交互方式。Session是Web应用中用于存储用户特定信息的一种机制,它允许开发者在用户的会话期间...
2. **URL重写(URL Rewriting)**:当服务器检测到客户端不支持Cookies时,它会通过URL重写的方式来传递Session ID。具体来说,服务器会在响应中返回的URL后面加上`;JSESSIONID=xxxxx`这样的参数,从而在客户端请求...
另一种应对方法由Likebao提出,核心思路是完全关闭Tomcat服务器上的Cookies支持,改为通过URL重写来传递Session ID。具体步骤如下: 1. **配置Tomcat**:在Tomcat的配置文件`XXApp.xml`中,设置`cookies="false"`,...
- Session是服务器端用来跟踪用户状态的一种机制。在用户登录成功后,服务器会返回一个Session ID,通常作为Cookie返回给客户端。客户端在后续的请求中需要带上这个Session ID,以表明其身份。 - 在Java中,可以...
这意味着客户端必须支持Cookie才能正常使用Session机制。如果不希望使用Cookie或者客户端禁用了Cookie功能,可以考虑使用URL重写(URL rewriting)作为替代方案,但这通常会导致URL变得比较复杂且不友好。 #### ...
如果Web服务需要处理与用户状态相关的请求,可以考虑将Session信息作为请求头的一部分传递,或者使用Token(如JWT)来替代Session,实现无状态的API设计。 总结来说,利用Redis实现Session共享可以有效地解决分布式...
4. **依赖性**:Session依赖于Cookie,如果客户端禁用Cookie,服务器可以通过URL重写技术传递SessionID,但这样会对URL产生污染,用户体验可能下降。 5. **安全性**:由于Session数据存储在服务器,相对Cookie来说...
每个用户在访问网站时会被分配一个唯一的会话ID(session ID),这个ID通过cookie或者URL重写等方式在客户端和服务器之间传递,使得服务器能够识别并跟踪特定用户的活动。 **二、session的工作原理** 当用户首次...
这时,服务器通常会采取URL重写的方式来传递Session ID。 #### 三、Session的工作原理 当用户首次访问服务器时,服务器会创建一个唯一的Session ID,并将其存储为一个名为`JSESSIONID`的Cookie发送给客户端。之后...
为了实现session共享,我们需要在Nginx配置中添加适当的cookie处理,例如设置`proxy_set_header`来传递JSESSIONID。 接着,我们讨论"memcache"。Memcached是一个高性能、分布式的内存对象缓存系统,用于减少数据库...
5. 为了使服务器能在后续请求中识别用户,服务器会将Session ID返回给客户端,通常通过设置一个名为`JSESSIONID`(或其他自定义名称)的Cookie实现。 6. 浏览器接收到Cookie后,会在后续对同一域名的请求中自动添加...
`session` 是服务器用来跟踪用户状态的一种机制,它存储了用户的登录信息、购物车数据等关键数据。在单个服务器环境中,`session` 存储在服务器内存中,但在集群环境中,由于用户请求可能被分发到不同的服务器实例,...
同时,添加`proxy_set_header`指令,将Session ID(JSESSIONID)传递给后端服务器。 5. **测试与优化**:启动所有服务,通过并发请求验证Session是否能在集群中正确共享。根据实际需求调整Nginx的负载均衡策略和...
在这样的架构中,Session管理变得复杂,因为Nginx并不直接处理Session,而是依赖于后端应用服务器的Session管理机制。 首先,我们需要理解Session的工作原理。当用户首次访问服务器时,服务器会为这个会话创建一个...
如果使用黏性会话,可以添加`proxy_set_header`来保存和传递JSESSIONID,以便在后续请求中保持session一致性: ```nginx location / { proxy_pass http://backend; proxy_set_header Host $host; proxy_set_...