用户会话在tomcat上混淆了

我们在IIS7.5之后使用Tomcat 6.29,使用spring,hibernate和struts2框架。 我们现在开始注意到服务器会话正在混淆,特别是在Ajax请求中。

关于这个问题的更多细节

  • 用户1请求page1,用户2请求page2。 但是user1获得了page2,而user2获得了server1。
  • 会话ID也在变化,但在刷新页面时,会提供正确的页面。
  • 当用户数量很多时,问题似乎更频繁发生。

任何指向问题根源的指针都会有所帮助,代码运行正常,用户数量较少,并且没有报告此类实例。

编辑

web.xml中

 bm  contextConfigLocation classpath:spring/*Context.xml   encodingFilter org.springframework.web.filter.CharacterEncodingFilter  encoding UTF-8   forceEncoding true    struts2 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter   encodingFilter /*   struts2 /*   org.springframework.web.context.ContextLoaderListener   org.apache.struts2.tiles.StrutsTilesListener  

在struts.xml

                        dojo\..*,^struts\..*        

其他信息

1)用户通过提交表单登录,登录时我们执行以下操作,

 public class xxxAction extends ActionSupport implements SessionAware { public String execute() { session.clear(); if (session instanceof org.apache.struts2.dispatcher.SessionMap) { try { ((org.apache.struts2.dispatcher.SessionMap) session).invalidate(); } catch (IllegalStateException e) { log.error("Session Invalidate Failed ", e); } //Authorization code happens here session.put("orgs", orgs); session.put("currentOrg", org); session.put("permission", adminDAO.getRolePermission(orgs.get(0).getRoleId())); session.put("simplyApp", simplyApp); session.put("user", user); return "login" } } 

2)使用的是Windows 2008 RC2

EDIT2 INCEPTOR CODE

INTERCEPTOR 1

 public String intercept(ActionInvocation invocation) throws Exception { String result = null; String className = invocation.getAction().getClass().getName(); Map session = invocation.getInvocationContext().getSession(); IRUser user = (IRUser) session.get("user"); IROrgname org = (IROrgname)session.get("currentOrg"); IRAppDetails simplyApp = (IRAppDetails)session.get("simplyApp"); String sessionId = (String)session.get("sessionId"); boolean switchUser =session.get("switchUser")!=null ? (Boolean)session.get("switchUser") : false; if(className.indexOf("IRLoginAction")!=-1 || className.indexOf("IRContactUsAction")!=-1 || className.indexOf("IRIPNAction")!=-1 || className.indexOf("IRPaymentAction")!=-1 || className.indexOf("IRServiceAction")!=-1 || className.indexOf("IRAppBossAction") !=-1) { result= invocation.invoke(); session.put("PREV_CLASS_NAME", className); } else if(!(className.indexOf("IRLoginAction")!=-1) && (user !=null && org!=null)) { if(!IRSessionManager.getInstance().compareSession(user.getUserId(), sessionId) && !switchUser) { session.clear(); if (session instanceof org.apache.struts2.dispatcher.SessionMap) { try { ((org.apache.struts2.dispatcher.SessionMap) session).invalidate(); } catch (IllegalStateException e) { log.error("Session Invalidate Failed ", e); } } result = "sessionDuplicated"; } else { result= invocation.invoke(); session.put("PREV_CLASS_NAME", className); } } else if(className.indexOf("widgets") !=-1) { result= invocation.invoke(); } else if(className.indexOf("ActionSupport") !=-1) { result= invocation.invoke(); } else if (!(className.indexOf("IRLoginAction")!=-1) && (user ==null || org==null || simplyApp==null)) { result = "sessionExpired"; } return result; } 

INTERCEPTOR 2

  public String intercept(ActionInvocation invocation) throws Exception { String result = null; HttpServletRequest request = ServletActionContext.getRequest(); String className = invocation.getAction().getClass().getName(); try { Map session = invocation.getInvocationContext().getSession(); IRUser user = (IRUser) session.get("user"); IROrgname org = (IROrgname)session.get("currentOrg"); IRAppDetails application = (IRAppDetails)session.get("simplyApp"); if(( user!= null && user.getAppType()!=0) && !(className.indexOf("IRLoginAction")!=-1)) { if(hasAccess(user.getAppType(), className)) { result= invocation.invoke(); } else { result = "checkURL"; } } else { result= invocation.invoke(); } } catch (Exception e) { e.printStackTrace(); } return result; } 

两天前我在遗留项目(不是我的)上调试了类似的东西。

原来这是自定义拦截器的错。

检查我在堆栈中可以看到的自定义拦截器,

    

并确保他们的代码是线程安全的 (避免拦截器上的字段而不是同步所有的东西,只使用局部变量)。

例如,考虑代码:

 public abstract class ThreadUnsafeInterceptor extends AbstractInterceptor { private Map session; //