`
gjtiancai
  • 浏览: 11702 次
  • 性别: Icon_minigender_1
  • 来自: 成都
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

jsessionid传递对session实现机制的影响

阅读更多
近期因工作需求探索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的页面跳转极其复杂,难于接受.
分享到:
评论

相关推荐

    理解session机制

    【全面理解Session机制】 Session机制是Web开发中用于维持客户端(浏览器)与服务器之间状态的一种技术。在HTTP协议中,由于其无状态性,每次请求之间不会共享任何信息,因此,为了实现用户登录状态的保持或者其他...

    javaWeb_Session(实现用户一段时间自动登录)

    综上所述,JavaWeb中的Session技术是实现用户自动登录的核心,它通过在服务器端存储用户信息并在客户端通过Cookie传递Session ID来保持用户状态。正确地配置和管理Session,能够为用户提供流畅的登录体验,同时也...

    Tomcat中实现Session小结

    总结来说,Tomcat中的Session是通过Session ID(JSESSIONID)作为标识,结合Cookie在客户端和服务器之间传递,实现对用户会话状态的跟踪。了解这些原理对于优化Web应用性能、处理会话管理问题以及确保用户安全性至关...

    使用session实现用户登录共4页.pdf.zip

    - **会话跟踪**:除了Cookie,还可以使用URL重写或者隐藏表单字段来传递Session ID,但Cookie是最常见的方法。 - **安全性**:需要注意Session劫持和Session固定攻击,可以通过使用HTTPS、定期更换Session ID、...

    一篇优秀Session讲解

    为了克服这一限制,引入了Session机制来维持会话状态。 2. **Cookie与Session的区别**:Cookie是在客户端存储信息的一种方式,而Session则是在服务器端存储用户会话信息的方式。两者都可用于跟踪用户状态,但Cookie...

    IFrame中Session丢失的解决办法

    P3P是一种隐私偏好平台,它影响了IE对第三方Cookies的处理,尤其是当它们嵌套在IFrame中时。 ### 解决方案 针对IFrame中Session丢失的问题,可以采取以下几种策略: 1. **使用StateServer模式管理Session:** 在...

    servlet中关于session的理解

    为了克服这一限制,Servlet容器(如Tomcat)提供了Session机制,用于保存用户状态信息,从而实现跨请求的数据共享。 #### Session对象创建与使用 当一个用户首次访问网站时,服务器会创建一个Session对象,并通过`...

    IE的cookie机制导致的session问题及解决办法.doc

    另一种应对方法由Likebao提出,核心思路是完全关闭Tomcat服务器上的Cookies支持,改为通过URL重写来传递Session ID。具体步骤如下: 1. **配置Tomcat**:在Tomcat的配置文件`XXApp.xml`中,设置`cookies="false"`,...

    java后台请求http并保持Session

    - Session是服务器端用来跟踪用户状态的一种机制。在用户登录成功后,服务器会返回一个Session ID,通常作为Cookie返回给客户端。客户端在后续的请求中需要带上这个Session ID,以表明其身份。 - 在Java中,可以...

    Session页面之间 传值

    这意味着客户端必须支持Cookie才能正常使用Session机制。如果不希望使用Cookie或者客户端禁用了Cookie功能,可以考虑使用URL重写(URL rewriting)作为替代方案,但这通常会导致URL变得比较复杂且不友好。 #### ...

    session与cookie.doc的区别

    4. **依赖性**:Session依赖于Cookie,如果客户端禁用Cookie,服务器可以通过URL重写技术传递SessionID,但这样会对URL产生污染,用户体验可能下降。 5. **安全性**:由于Session数据存储在服务器,相对Cookie来说...

    redis的session共享

    如果Web服务需要处理与用户状态相关的请求,可以考虑将Session信息作为请求头的一部分传递,或者使用Token(如JWT)来替代Session,实现无状态的API设计。 总结来说,利用Redis实现Session共享可以有效地解决分布式...

    6 jsp内建对象之session

    每个用户在访问网站时会被分配一个唯一的会话ID(session ID),这个ID通过cookie或者URL重写等方式在客户端和服务器之间传递,使得服务器能够识别并跟踪特定用户的活动。 **二、session的工作原理** 当用户首次...

    nginx配置session+memcached所需jar包

    为了实现session共享,我们需要在Nginx配置中添加适当的cookie处理,例如设置`proxy_set_header`来传递JSESSIONID。 接着,我们讨论"memcache"。Memcached是一个高性能、分布式的内存对象缓存系统,用于减少数据库...

    session和cookie详解

    由于HTTP协议本身是无状态的,即服务器无法自动记录客户端的状态信息,因此需要通过Session和Cookie等技术手段来实现对用户状态的追踪。 - **Session**: 会话是指用户与服务器进行交互的过程中的一系列连续请求和...

    nginx+tomcat集群的jar包 session共享

    `session` 是服务器用来跟踪用户状态的一种机制,它存储了用户的登录信息、购物车数据等关键数据。在单个服务器环境中,`session` 存储在服务器内存中,但在集群环境中,由于用户请求可能被分发到不同的服务器实例,...

    session登录 demo

    5. 为了使服务器能在后续请求中识别用户,服务器会将Session ID返回给客户端,通常通过设置一个名为`JSESSIONID`(或其他自定义名称)的Cookie实现。 6. 浏览器接收到Cookie后,会在后续对同一域名的请求中自动添加...

    nginx反向代理导致session失效的问题解决

    在这样的架构中,Session管理变得复杂,因为Nginx并不直接处理Session,而是依赖于后端应用服务器的Session管理机制。 首先,我们需要理解Session的工作原理。当用户首次访问服务器时,服务器会为这个会话创建一个...

    tomcat8-session共享

    同时,添加`proxy_set_header`指令,将Session ID(JSESSIONID)传递给后端服务器。 5. **测试与优化**:启动所有服务,通过并发请求验证Session是否能在集群中正确共享。根据实际需求调整Nginx的负载均衡策略和...

    JSP session配置对web应用的影响

    然而,不恰当的JSP session配置可能会对web应用程序的性能产生显著影响,如内存消耗过大、垃圾回收(GC)频率过高,甚至可能导致服务器性能下降。 **1. Session的工作原理** Session是服务器端的一种存储机制,...

Global site tag (gtag.js) - Google Analytics