Java 在原始接收线程之外访问HttpSession
我用的是Spring3。当控制器收到请求时,它将控制权传递给服务bean中带有Java 在原始接收线程之外访问HttpSession,java,spring,asynchronous,httpsession,Java,Spring,Asynchronous,Httpsession,我用的是Spring3。当控制器收到请求时,它将控制权传递给服务bean中带有@Async注释的方法someMethod(),然后返回。当我在someMethod()HttpSession对象中访问时,我收到此异常 java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or
@Async
注释的方法someMethod()
,然后返回。当我在someMethod()
HttpSession对象中访问时,我收到此异常
java.lang.IllegalStateException: No thread-bound request found: Are you
referring to request attributes outside of an actual web request, or
processing a request outside of the originally receiving thread? If you are
actually operating within a web request and still receive this message, your
code is probably running outside of DispatcherServlet/DispatcherPortlet: In
this case, use RequestContextListener or
RequestContextFilter to expose the current request.
如何解决此问题?HttpSession对象本身可以在多个线程中使用(但不是线程安全的,因此必须同步)。然而,Spring正在发挥一些额外的魔力,例如,当您拥有
会话
范围的bean时。也就是说,它在下面使用ThreadLocal
将当前会话与线程绑定
我不知道您的具体场景是什么,但显然Spring试图在您处于另一个线程时从该ThreadLocal
检索HttpSession
,这显然失败了
解决方案很简单-在
@Async
方法中提取所需的会话属性并直接传递它们。顺便说一句,这是更好的设计-避免传递HttpSession
对象,因为这会使测试更加困难,并且您的代码在将来不太可能被重用。您的解决方案简单且良好,但是如果我不仅在控制器层而且在业务和数据中需要用户特定的数据,我可以将它们存储在哪里层?或者我必须通过方法参数传递这些数据?后者是唯一的解决方案吗?@OleksandrBondarenko:想想看——通过访问服务层中的会话,您引入了隐藏耦合和非显式依赖。通过参数传递所有这些数据(可能通过将其包装到某个对象中)确实是最好的选择。但是在会话上设置如何呢?您是否有任何文档来支持您可以在请求之外访问HttpSession的断言?