Struts 2重置动作实例,而它仍处于拦截器中

似乎如果我对同一个动作有两个并发请求,例如mysite.com/fooAction,那么struts会重置第一个动作的实例,而该实例可能仍在拦截器中。

例如,如果我的拦截器中有以下代码:

action = ai.getAction(); String result = ai.invoke(); logger.debug("Orig action : " + action.toString() +" , now : " + ai.getAction().toString() ); 

如果我对同一个动作发出两个并发请求(例如使用javascript),那么该行:

 logger.debug("Orig action : " + action.toString() +" , now : " + ai.getAction().toString() ); 

生成两个不同的toString()代码,显示原始操作与上一个操作位于不同的实例中。

这是一个很大的问题,因为现在,如果我在拦截器中有任何代码,它会在我的操作中设置某些内容,例如执行以下操作:

 MyAction action = (MyAction) ai.getAction(); Auth auth = new Auth ( action.getSession() ); action.setAuth(auth); action.setCookiesMap( Util.getAllCookies() ); String result = ai.invoke(); 

那么我无法保证我在行动中设置的所有内容实际上都会传递给正确的实例。 也就是说,当ai.invoke()时,它实际上可能会调用一个完全不同的动作实例,它具有不同的cookie或其他数据集。 这可能导致不同的用户被访问彼此的数据。

我在所有这些方面都是正确的吗? 如果是这样,这个问题有解决方案吗? 因为这似乎完全打败了拦截器的目的。

如果我正确理解了问题 – 如果发出单个请求,则打印操作引用的结果表明它们是相同的。

但是,如果发出并发请求,则操作引用会有所不同。

如果确实如此,则可能是由于自定义。

默认情况下,在DefaultActionInvocation情况下初始化’action’引用的唯一位置是createAction ,而createAction仅在同一个类中的init(ActionProxy)中调用,而后者应该只调用一次并完成来自DefaultActionProxy的prepare(),而后者仅从DefaultActionProxyFactory的createActionProxy()调用。

因此,对于给定的ActionInvocation实例,操作将(应该)始终相同。

更新2 ( 关于示例s2项目 ):

虽然我实际上没有运行代码,但我确实经历过。

Json拦截器是有状态的。 但是,它必须是无国籍的。 这解释了为什么并发请求导致操作实例不同。

根据这里的拦截器文档:

拦截器是遵循拦截器模式的无状态类,如javax.servlet.Filter和AOP语言中所示。

拦截器必须是无状态的,并且不假设将为每个请求或Action创建新实例。

据我了解:

第一个请求在拦截器中分配本地Action实例并进入hibernate状态。

第二个请求重新分配Action实例(拦截器是单例)并且也进入hibernate状态。

第一个请求唤醒并继续执行。 在返回并再次比较动作实例时,从第二个请求中查看拦截器中的Action实例,并再次从ActionInvocation获取当前请求的动作实例。 他们确实会有所不同。 这解释了观察到的行为。 此外,即使未调用ai.invoke()或ai.invokeActionOnly(),它也应该是可见的。

‘servletConfig’拦截器也已包含在’defaultStack’中,还包含其他一些拦截器。 你可以在这里找到详细信息