我尝试在控制器中使用返回类型 Callable 以便在处理请求时释放 servlet 线程,但是当在开发环境中部署 Spring Boot 应用程序时出现以下错误:
org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常是 java.lang.IllegalStateException:必须在 servlet 上以及异步请求处理中涉及的所有过滤器上启用异步支持。这是使用 Servlet API 在 Java 代码中或通过将“true”添加到 web.xml 中的 servlet 和过滤器声明来完成的。
注意:我已经阅读了几篇有关此错误的文章,但没有一个解决了我的问题。
我遇到的特殊行为是,本地一切都按预期工作:servlet 线程被释放,请求在带外处理,最终返回给客户端所需的响应。
但是,当应用程序部署在前面提到的开发环境中时,事情就无法按预期工作。
在本地测试时,我检查了 servlet/filters 是否支持异步;在调试时,我只需在给定的过滤器中放置一个断点ApplicationFilterChain,然后检查整个链。在那里,我可以检查 servlet 属性(其中我看到 asyncSupported 设置为 true)以及链中包含的每个过滤器(我一一检查了它们;所有它们的 asyncSupported 设置为 true)。
我还有一个自定义JwtAuthenticationFilter,它是AbstractAuthenticationProcessingFilter身份验证阶段的一部分,因此我还在此类过滤器中放置了一个断点并检查链。在那里我看到了originalChain(ApplicationFilterChain之前评论过的)和“additionalFilters”集合,其中出现了我的JwtAuthenticationFilter以及spring安全过滤器。但它们都没有 asyncSupported 属性,所以我假设它们不是开发服务器抛出的错误的一部分。请注意,正如我在本地提到的,一切正常;该错误仅在部署到开发服务器时出现。
控制器方法:
@GetMapping(path = "/export")
public Callable<ResponseEntity> exportData() throws IOException {
return new CustomContextAwareCallable(() -> handleResponse());
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:即使 ApplicationFilterChain 上的每个过滤器以及 servlet 都将 asyncSupported 设置为 true,为什么我在部署后会从服务器收到上面显示的错误?
该应用程序没有作为 .WAR 部署在服务器上,它只是使用嵌入式 tomcat(与我在本地执行的操作相同)。
更新:另一个区别是,在开发环境中客户端请求通过 nginx 代理传递(只是想知道是否由于某种原因请求属性 …