一直都没怎么记录技术文章的日志了。这回个小问题花了比较久的时间,感觉还是记录下来以便以后查阅和帮助遇到同类问题的朋。其实在网上一搜session丢失,大把的都是讲session超时和跨域的iframe的问题。其实我碰到的问题和这些都不是。首先来描述下问题的情况吧。
1首页index.jsp登陆----》2登陆action创建新session---》3返回到一个有装饰器的页面----》4点一级菜单,开始报错找不到session里的值。
以上情况在外网发生较多。局域网很少发生。
分析1:是否session没有在登陆时创建成功? 通过环节3,有个从session中取值的过程。正常,排除
分析2:是否登陆后session超时或者被销毁?通过加入自己的session监听器观察(继承HttpSessionListener),没有发现有session的销毁
问题就应该在jsessionId的赋值问题上。web程序走http协议是没状态的,session更客户端的关联是通过jsessionId来维持的这个大家都应该知道。
分析3:所以先检查是不是客户端的cookies禁用的情况。于是在环节3的页面加入cookies开启判断的js。发现没有出提示。应该不是客户端偶尔的cookies经用和写入问题。(这里顺便说下,各个浏览器对一个域名下的cookies记录有上限,ie应该是20)
此时在用FF跟踪JSESSIONID时发现登陆后有两个。
分析4:是否是TOMCAT对多个jsessionId的处理规则导致没有关联到登陆后的那个session。发现两个jsessionId生成的原因在于www.denglish.cn下会产生一个,然后到了www.denglish.cn/exam这个子域也会产生一个。浏览器一般的规则是,子域提交的请求,也会把父域的cookies提交上去。(顺带做了个测试,用js往cookies写入一个和登陆session域一样但是值不一样的jseesionId,tomcat在处理两个jseesionId时还是会自动找到那个session。这里有点不明白了,不管我把手动创造的假jseesionId放在cookies的前面还是后面都是一样的情况,估计tomcat是不是两个都去配置,如果有session返回就返回。这个要看源码认证下)
由于用FF的网络包跟踪看不出问题,在IE上装httpwarcher然后把本机的网速调慢终于发现了问题:首页有一个AJAX请求,是写在了DOMREADY里的,如果网速过慢,会在登录的ACTION提交过后该AJAX请求才提交,并且该AJAX请求居然返回了个新的就JSESSIONID,于是由于域相同,覆盖了COOKIES里对应了登陆信息的JSESSIONID。 对于网速过慢,AJAX请求发出在登录请求之后这个问题解决不了,调为同步也不行。那么分析为什么会有个新的JSESSIONID呢,如果在首页就执行了AJAX请求为什么就没新的JSESSIONID返回?
为此查找了tomcat建立session的源码。可见我转载的《Tomcat源码---Session的分析》。发现只有在新加了session的时候才会有JSESSIONID写回到cookies
分析5:由于登录ACTION的代码里是登录验证通过后先把原先的session给invalidate掉然后新建一个session,那么过登录的请求在AJAX请求之前,就会让AJAX里JSESSIONID对应的SESSION失效,所以AJAX会重新建立一个SESSION并返回JSESSIONID。但是AJAX请求没涉及到新建SESSION的操作,为什么会有判断SESSION失效的代码执行呢。
这里还有个知识点,如果访问JSP页面,么有显示的写入<%@ page session="false"%>那么在编译的SEVLET里会有段代码, session = pageContext.getSession();对于网速查阅的pageContext.getSession()等同于request..getSession()那么这里就会判断session是否存在,并且会在判断没有的时候新建session。 但是当在ajax的返回JSP里加入<%@ page session="false"%>依旧发现其返回了新的jsessionid。
分析6:还有其它的什么地方再判断SESSION并新增了。
通过对HttpSessionAttributeListener的继承,跟踪到了新增SESSIOIN的属性,其中发现了name:org.apache.struts.action.LOCALE 和value: zh_CN。这个是struts的国际化自己建立的session。会在.do的请求和通过<forward>标签的url都会执行setLOCAL方法建立session。
原因都已经找到,如果解决由多种方案,权衡了几种:
1:首页不用AJAX。其实首页本来就不应该有过多复杂的代码,但是考虑到AJAX的返回JSP会在别的地方有重用,为避免代码不一致的问题,还是保留了首页目前还是用AJAX的方法
2:取消国际化所新加的SESSION。目前还没找到直接配置国际化开关的选项,而且以后万一在登录后有返回新SESSION的地方还是会出现此问题,首页该方案不可取
3:修改登录的ACTION,登录成功后保留原先的SESSION。该方法有安全隐患,如果黑客和你公用一个JSESSIONID时,你登陆后的状态会在他刷新后也可以看到。
4:修改登录的ACTION,登录后新建SESSION,但是原先的SESSION不要invalidate。这样国际化标签不会产生新的SESSION。注意首页不要写<%@ page session="false"%>。应该让其有一个SESSION。这个方案的坏处就是可能会有些无用的SESSION要等到超时才会回收,不过这个问题在客户登陆后直接关掉浏览器也会有,所以影响应该不是很大。
个人比较倾向于方案4.不过应该也有别的方法来保证JSESSIONID不给覆盖,但是可能会比较复杂点。在此就不深入研究了。最后简略画个流程图来描述问题发生的原因。
访问域名www.denglish.cn :此时建立一个JSESSIONID
ˇ
自动跳转到首页www.denglish.cn/exam/index.jsp: 由于是子域 所以产生新的JSESSIONID 比如是AAA
ˇ
ˇ
ˇ
index.jsp加载:但是由于网速过慢DOM没完全加载完所以AJAX的请求还没提交,但是会缓存后排队提交
ˇ
提交登陆的请求:但是此时首页还没加载完,所以AJAX还没提交
ˇ
登陆请求返回:登陆ACTION中为了安全起见,invalidat掉了旧的session生成了新的session,并回写了新的jsessionid比如是BBB到客户端cookies
AJAX请求提交:国际化标签会过滤请求判断其自己的SESSION是否存在。由于此请求带过去的JSESSIONID 还是AAA,对应的SESSION已经给invalidat掉了,所以产生新的SESSION返回jsessionid比如是CCC,写入客户端COOKIES
ˇ
点击其它需要获取登陆信息的页面:由于此时提交的jsessionid是CCC,对应的SESSION是国际化的SESSION并非登陆的,所以报错
问题明了后。虽然是很小的一个细节问题,但是知道了很多与SESSION相关的原理。好记性胜不过烂笔头。还是记录一下。
分享到:
相关推荐
在Web开发中,Session是服务器用来跟踪用户状态的一种机制,特别是在多用户同时访问的应用中,如EXT(ExtJS)框架创建的富客户端应用。当Session失效时,通常会导致用户被重定向到登录页面,以便重新验证其身份。...
设置Session失效的几种方法可以根据实际情况选择,既可以在主页面或公共页面中设置,也可以在项目的web.xml中设置,也可以直接在应用服务器中设置。此外,使用HttpSessionListener可以监听Session的生命周期,执行...
描述中的博文链接指向了一篇关于该主题的博客文章,尽管具体内容没有给出,但我们可以推测博主可能讨论了Session失效的原因、影响以及解决方法。 首先,我们需要理解Session的工作原理。在HTTP协议中,由于其无状态...
Session失效是指当一个Session因过期或被主动销毁而无法继续使用的情况。在实际应用中,Session的生命周期可以通过设置最大非活动间隔(Max Inactive Interval)来控制。该参数定义了从最后操作Session到Session自动...
最近由于一个项目,模块切换为ajax请求数据,当Session失效后,ajax请求后没有返回值,只有响应的html:<html>[removed]window.open(‘http://192.168.0.118:8080/welcomeAction/loginUI.do’,’_top’);...
要在Session失效后保留表单数据,有两种常见策略: - **临时存储**:在用户被重定向到登录页面时,将表单数据暂存到服务器的某个地方(如服务器端的内存、数据库或Cookie)。登录成功后,根据存储的数据填充表单。...
一同事求援:后台系统的登录成功了,但不能成功登进系统,仍然跳转到登录页,但同一套代码另一个环境却没有问题。 背景 经了解,他对同一个项目使用tomcat部署了两个环境,一个在开发服务器上,一个在他本机,两个...
5. **代码错误**:编程错误,如不当的Session管理,可能导致Session意外失效。开发人员应遵循最佳实践,例如在处理完特定操作后及时清理不再需要的Session,避免 Session 冲突。 6. **安全措施**:有些安全设置,如...
ASP.NET 跨域与 Session 失效问题的解决办法 在 ASP.NET 开发中,跨域和 Session 失效问题是一个常见的问题,特别是在使用 iframe 嵌入远程应用时。今天,我们来讨论这个问题的解决办法。 什么是跨域和 Session ...
对于基于权限认证的Action,无论是否是Ajax请求,AuthorizeAttribute都能捕获到Session失效的情况。当Session失效时,我们可以自定义AuthorizeAttribute的子类,如`AuthorizeOfHandleUnAuthorizeAttribute`,并在`...
使用filter来做后台,Ext.Ajax.on('requestcomplete', checkUserSessionStatus, this);用requestcomplete这个方法来异步判断session是否已经失效了
开发者需要根据具体情况来分析并配置session的相关参数,比如设置session的最大有效时间、自定义session的失效策略等,以确保应用的性能和数据安全。在FineReport这类报表工具中,还需考虑到报表特有的session管理...
然而,在某些情况下,如标题所示,“session在httphandler失效”,这可能会导致应用程序出现问题。下面将详细解释这个问题,以及可能的原因和解决方案。 首先,让我们理解Session的工作原理。ASP.NET的Session是...
Session是Web应用程序用来存储用户特定数据的一种机制,通常存储在服务器端,而Session ID通过Cookie在客户端与服务器之间传递。当用户在不同域之间跳转时,如果不进行特殊处理,Session信息将无法跨域共享。 以下...
在IT领域,尤其是在Web开发中,"Session状态失效"是一个常见的问题,涉及到用户在网站上的交互体验和数据管理。本文将深入探讨这个问题,包括它的原因、影响以及如何解决。 首先,Session是Web应用程序中用于存储...
在探讨如何解决iframe跨域与session失效的问题之前,我们需要了解几个重要的概念:什么是跨域,什么是session以及cookie。 首先,跨域问题通常出现在Web应用中,尤其是在使用iframe嵌入第三方网站内容时。在Web技术...
昨天去GTSC面试,有面试官问我关于Session丢失之后怎么查的问题,说老实话,开发到现在很少碰到这样的情况,唯一想到的就是Session超时,还有就是做Session读写日志,发觉面试官听了之后不是很满意,汗! 不管怎么说...
首先,Session的失效时间可以通过以下三种方式设置,其优先级从高到低依次为: 1. **Java代码设置**:通过`request.getSession().setMaxInactiveInterval(int seconds)`方法,以秒为单位设置Session的失效时间。...