Scope 'session' is not active for the current thread; IllegalStateException: No thread-bound request found 作用域为'session'的内容对于当前线程不活动;IllegalStateException: 未找到与线程绑定的请求

14 浏览
0 Comments

Scope 'session' is not active for the current thread; IllegalStateException: No thread-bound request found 作用域为'session'的内容对于当前线程不活动;IllegalStateException: 未找到与线程绑定的请求

我有一个控制器,我希望每个会话都是唯一的。根据Spring文档的说明,实现有两个关键点:

1. 初始Web配置

为了支持请求、会话和全局会话级别的bean(Web范围的bean)的作用域,您需要在定义bean之前进行一些初始配置。

我已按照文档中的示例将以下内容添加到我的web.xml中:


  
    org.springframework.web.context.request.RequestContextListener
  

2. 作为依赖项的作用域bean

如果您想将(例如)一个HTTP请求作用域的bean注入到另一个bean中,您必须在作用域bean的位置注入一个AOP代理。

我已经使用@Scope注解为该bean提供了proxyMode,如下所示:

@Controller
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class ReportBuilder implements Serializable {
    ...
    ...
}

问题

尽管进行了上述配置,但我收到以下异常:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.reportBuilder': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is 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.

更新1

以下是我的组件扫描。我在web.xml中有以下内容:


  contextClass
  
    org.springframework.web.context.support.AnnotationConfigWebApplicationContext
  


  contextConfigLocation
  org.example.AppConfig


  org.springframework.web.context.ContextLoaderListener

并且在AppConfig.java中有以下内容:

@Configuration
@EnableAsync
@EnableCaching
@ComponentScan("org.example")
@ImportResource("classpath:applicationContext.xml")
public class AppConfig implements AsyncConfigurer {
  ...
  ...
}

更新2

我已经创建了一个可复现的测试案例。这是一个更小的项目,所以有一些差异,但是发生了相同的错误。由于文件较多,我已将其上传为tar.gzmegafileupload

0
0 Comments

问题的出现原因是在代码设计模式中混合了不同的作用域和线程:

- 单例模式(singleton)

- 会话模式(session)或请求模式(request)

- 作业线程池(thread pool of jobs)

单例模式在任何地方都可用,这是可以的。然而,会话模式或请求模式只能在附加到请求的线程中使用,而异步作业可以在请求或会话不存在的情况下运行,因此无法使用依赖于请求或会话的bean。此外,无法确定在单独的线程中运行作业时,原始请求是哪个线程(这意味着在这种情况下aop:proxy无济于事)。

解决方法是:

- 尝试简化代码,不再使用ReportBuilder。

- 使用org.springframework.web.context.request.RequestContextListener而不是RequestContextListener,因为你没有使用Dispatcher Servlet。

- 如果你的问题是在使用OAuth2RestTemplate时出现的,尝试将其作用域更改为原型(prototype)。

以上是关于(Scope 'session' is not active for the current thread; IllegalStateException: No thread-bound request found)问题的原因和解决方法的整理。

0
0 Comments

问题的原因是在当前线程中没有活动的会话(session),导致了 IllegalStateException 异常。解决方法是在web.xml中添加一个监听器(RequestContextListener),在会话组件中设置session的作用域为session,并在pom.xml中添加cglib依赖。

具体的解决步骤如下:

1. 在web.xml文件中添加以下代码:


    org.springframework.web.context.request.RequestContextListener

2. 在会话组件中添加以下代码,将session的作用域设置为session:

@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)

3. 在pom.xml文件中添加以下代码,添加cglib依赖:


    cglib
    cglib
    3.1

另外,也可以使用ScopedProxyMode.INTERFACE而不需要cglib依赖。在这种情况下,需要一个接口。

以上方法解决了该问题,同时也提到了在Spring框架版本3.2以后,不再需要添加CGLIB的显式依赖。可以在此链接中获取更多详细信息:docs.spring.io/spring/docs/3.2.x/spring-framework-reference/…

0
0 Comments

问题原因:这个问题的原因是使用了多线程。请求对象在这些线程中不可用。

解决方法1:可以将请求对象提供给其他线程,但这会对系统施加一些限制,可能在所有项目中都无法工作。可以使用SimpleAsyncTaskExecutor代替WorkManagerTaskExecutor/ThreadPoolExecutorFactoryBean来解决这个问题,并且使用RequestContextFilter代替RequestContextListener。在RequestContextFilter中设置threadContextInheritable属性,允许子线程继承父线程的上下文。

解决方法2:另一个选择是在请求线程中使用会话作用域的bean。但在某些情况下,这可能不可行,例如控制器方法使用了@Transactional注解,或者控制器方法启动了使用线程执行并行作业步骤的批处理作业。

如果以上解决方法都不起作用,可以查看这个链接:medium.com/_maniar/...

0