当前位置: 首页 > 知识库问答 >
问题:

继承的ServletRquestAttributes在Spring Boot中子线程完成之前被标记为完成

拓拔元徽
2023-03-14

我使用的是SpringBoot 1.5.2版本。我有一个异步REST调用,它产生单独的java线程来完成长时间运行的作业。长时间运行的工作需要更新DB表,在这里我配置了Spring审计bean来使用当前登录用户名更新表。我得到的问题是:在通过调用setThreadContextInheritable(true)启用inheritable标志之后,传递给进行长时间运行的DB更新的子线程的ServletRequestAttributes对象在子线程完成其任务之前被标记为“inactive”,这导致了当审计bean试图访问缓存在RequestContexTholder中的ServletRequestAttributes中的用户名时的错误。

若要打开可继承标志,请参阅作用域“会话”对当前线程不是活动的;IllegalStateException:未找到线程绑定请求

  1. 在application.java中
java prettyprint-override">@Override
public Executor getAsyncExecutor() {
    SimpleAsyncTaskExecutor executor = new
        SimpleAsyncTaskExecutor(appProperties.threadNamePrefix);
    return executor;
}
@Bean
public ServletRegistrationBean registerAirportDispatchServlet() {
    DispatcherServlet dispatcherServlet = new DispatcherServlet();
    AnnotationConfigWebApplicationContext applicationContext =
        new AnnotationConfigWebApplicationContext();
    dispatcherServlet.setApplicationContext(applicationContext);
    dispatcherServlet.setThreadContextInheritable(true);
    ServletRegistrationBean servletRegistrationBean =
        new ServletRegistrationBean(dispatcherServlet, "/*");
    servletRegistrationBean.setName("AirportSCSDispacherServlet");
    return servletRegistrationBean;
}
@Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public AccessToken getAccessToken() {
    RequestAttributes attribs =
        RequestContextHolder.getRequestAttributes();
    //do something with the attribs here...
    return token;
}

是的,我必须注册我的DispatcherServlet并在那里设置标志,而不是使用RequestContextFilter和RequestContextListener,因为在请求过滤的路径下,DispatcherServlet将inheritable flag设置为false,这将覆盖链前面从RequestContextFilter和RequestContextListener设置的true标志。通过调试,我可以看出FrameworkServlet的方法processRequest()是DispatcherServlet的超类,它调用RequestAttributes.RequestCompleted();在第989行,这个requestAttributes对象作为新生成线程的继承属性保存在RequestContextHolder中,当新线程试图为AccessToken获取这个属性时,Spring framework会抛出错误,因为它被标记为inactive。我尝试了会话范围,它不起作用,因为我的REST调用不在会话中,我使用Keycloak进行身份验证,所以请求属性中包含字符串访问令牌。

我在这里问:有没有更好的方法,我可以保持这个继承的请求属性对象仍然处于活动状态?

共有1个答案

白腾
2023-03-14

我也遇到了同样的问题。我的应用程序正在启动一个异步线程,然后立即向客户端发送http响应。当我尝试在异步线程中获取属性时,已经发送了响应,requestActive字段为false。这就是这个错误的原因。我们不能在外部设置RequestActive字段。Spring将根据http请求状态处理该字段。

 类似资料:
  • 我正在使用JBPM 5.4.0和通过spring容器创建的注入以及本地任务服务。我在会话中注册了一个LocalHttItemHandler,但即使在将我的任务标记为Complete(完成时没有问题)之后,流也不会继续。这里会出什么问题? 即使使用LocalTaskService,我也需要启动任务服务器吗?

  • 问题内容: 主线程将在子线程完成执行之前退出? 我读了两篇文章 http://www.cs.mtu.edu/~shene/NSF-3/e-Book/FUNDAMENTALS/thread- management.html 在以上文章的“线程终止”段中,它用红色表示“如果父线程终止,则其所有子线程也终止。” http://www.roseindia.net/java/thread/overview-

  • 这是我正在研究的完全未来的例子 首先我从SupplySync调用compose方法,在这里我执行方法composeMethod,有三毫秒的延迟,然后它将创建一个文件并返回一个字符串作为结果。完成后,我调用Run方法,它只打印一个方法,然后有一个非阻塞方法从主线程运行。 我在这里面临的问题是,主线程执行完nonblockingmethod()并在3毫秒延迟之前退出进程,而随后的composeMeth

  • 我试图理解Python线程的“守护进程”标志。这我知道 线程可以标记为“守护线程”。此标志的意义在于,当只剩下守护进程线程时,整个Python程序将退出。初始值从创建线程继承。 但在我的例子中,python程序在守护进程线程离开并且线程没有完成其工作之前退出。 主程序 第一个线程只写5000个第一个整数,而第二个线程不写任何数字

  • 我有一个用于交互式过渡的自定义动画师。还有一个,根据过渡进度设置为。效果的动画代码如下: 我通过调用它,当从它到第一个的转换开始时,它在第二个上调用。 然而,我这里有一个问题。在动画结束之前调用完成块。当我第一次运行转换(没有取消它)时,它工作得很好,但在随后的运行过程中,它就不工作了。 我也曾尝试将动画添加到我的动画师中,但也没有成功。 此外,当我取消转换时,在实际动画结束之前调用完成块(在这种

  • 问题内容: 问题描述 : - 步骤1: 在主线程中从用户那里获取输入FILE_NAME。 步骤2: 对该文件执行10个操作(即,计数字符,计数行等。),所有这10个操作必须位于单独的线程中。这意味着必须有10个子线程。 步骤3: 主线程等待,直到所有那些子线程完成。 步骤4: 打印结果。 我做了什么 :- 我用3个线程做了一个示例代码。 我不希望您遇到文件操作代码。 问题:- 我上面的代码没有给出