gpt4 book ai didi

java - 在 Spring Boot 中,继承的 ServletRequestAttributes 在子线程完成之前被标记为完成

转载 作者:行者123 更新时间:2023-12-01 18:22:30 24 4
gpt4 key购买 nike

我正在使用 SpringBoot 1.5.2 版本。我有一个异步 REST 调用,它会生成单独的 java 线程来完成长时间运行的作业。长时间运行的作业需要更新数据库表,我将 Spring 审核 bean 配置为使用当前登录用户名更新表。我遇到的问题是:通过调用 setThreadContextInheritable(true) 启用可继承标志后,传递到执行长时间运行的数据库更新的子线程的 ServletRequestAttributes 对象在子线程完成其工作之前被标记为“非 Activity ”,最终导致当审核 bean 尝试从 RequestContextHolder 中缓存的 ServletRequestAttributes 访问用户名时出错。

开启可继承标志,请引用Scope 'session' is not active for the current thread; IllegalStateException: No thread-bound request found

这是获取我到目前为止所拥有的主要代码:

  1. Application.java
@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 将可继承标志设置为 false,这将覆盖链中较早的 RequestContextFilter 和 RequestContextListener 设置的 true 标志。通过调试,我可以看出 FrameworkServlet 的 processRequest() 方法是 DispatcherServlet 的父类(super class),它在第 989 行调用 requestAttributes.requestCompleted(); ,而这个 requestAttributes对象作为新生成的线程的继承属性保存在 RequestContextHolder 中,当新线程尝试获取 AccessToken 的此属性时,Spring 框架会抛出错误,因为它被标记为非 Activity 状态。我已经尝试过 SESSION 范围,但它不起作用,因为我的 REST 调用不在 session 中,我使用 Keycloak 进行身份验证,因此请求属性中包含字符串访问 token 。

我在这里问:有没有更好的方法可以让这个继承的请求属性对象保持 Activity 状态?

最佳答案

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

关于java - 在 Spring Boot 中,继承的 ServletRequestAttributes 在子线程完成之前被标记为完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44121654/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com