【问题标题】:Attributes set in RequestContextHolder lost after response is returnedRequestContextHolder 中设置的属性在返回响应后丢失
【发布时间】:2017-02-08 03:20:11
【问题描述】:

我在 SpringBoot 中公开了一个服务,并且我在 RequestContextHolder 中存储了一些属性。在我的一个 API 中,我必须异步执行一些活动。应用程序接受一个请求并创建一个新线程来执行该活动并立即返回响应。我也将 RequestContextHolder 对象传递给线程。线程尝试从 RequestContextHolder 获取属性,并且在发送响应后看起来它为空。如果我在线程完成执行后返回响应,则该值在线程中可用。我假设 RequestContextHolder 与 HTTPRequest 绑定,并且在返回响应时丢失。我的假设正确吗?如果是这样,我该如何处理这种情况?

org.springframework.web.context.request.RequestContextHolder

【问题讨论】:

  • 请求存储在 ThreadLocal 变量中,因此在执行异步任务时,该变量可以有另一个请求,也可以没有。只需在执行之前获取所需的属性并传递给您的任务。
  • 谢谢@YevheniiMelnyk。那么返回响应时变量会被销毁吗?
  • 是的 RequestContextHolder.resetRequestAttributes() 在请求被处理后被调用。在 Spring Boot App 中,RequestContextFilter 默认负责这个。
  • 谢谢@YevheniiMelnyk。我创建了一个线程局部变量并存储了我需要的值。如果您可以将其发布为答案,我会接受。
  • 我没有明白你的意思,但是在处理来自另一个线程的数据时使用 threadlocal 存储任何东西是不安全的。只需在执行前获取参数并将它们传递给执行任务的构造函数。或者制作匿名 Callable 并将其用作已经检索到的值而不是 ThreadLocal 的 clousure。您也可以直接从控制器返回可调用对象,spring 将异步处理结果。如果你能告诉你使用什么样的异步执行以及用于什么,它会有所帮助。

标签: java spring spring-boot


【解决方案1】:

在 Spring Boot 应用程序中,RequestContextFilter 将请求设置为 RequestContextHolder,并将其存储为线程局部变量,并在控制器返回后将其清除。使用 RequestContextHolder 作为另一个线程的参数是不正确的方法,因为它的内容在处理过程中会发生变化。

在 RequestContextHolder.getRequestAttributes() 开始新的并发任务之前使用实际请求,它包含所有属性集,只是一个没有 ThreadLocal 的普通对象。

【讨论】:

  • 非常感谢@Yevhenii Melnyk。也感谢您对我的回答的回复。我正在尝试运行测试,运行后会请求您的帮助。
猜你喜欢
  • 2023-03-13
  • 2013-03-23
  • 2012-06-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多