【发布时间】:2018-10-01 19:24:48
【问题描述】:
我试图在控制器中使用返回类型 Callable 以便在处理请求时释放 servlet 线程,但是在开发环境中部署 Spring Boot 应用程序时出现以下错误:
org.springframework.web.util.NestedServletException: 请求 处理失败;嵌套异常是 java.lang.IllegalStateException:必须在 servlet 和异步请求处理中涉及的所有过滤器。这 在 Java 代码中使用 Servlet API 或通过添加 \"true\" 到 servlet 和过滤器 web.xml 中的声明。
注意:我已经阅读了几篇关于此错误的帖子,但都没有解决我的问题。
我的特殊行为是本地一切都按预期工作:释放 servlet 线程并带外处理请求,最终将所需的响应返回给客户端。
但是当应用程序如前所述部署在开发环境中时,事情并没有按预期工作。
在本地测试时,我检查了 servlet/过滤器是否支持异步;要在调试时做,我只是在ApplicationFilterChain 的给定过滤器中放置一个断点,然后检查整个链。在那里我可以检查 servlet 属性(我看到 asyncSupported 为 true)以及链中包含的每个过滤器(我一一检查它们;它们都将 asyncSupported 设置为 true)。
我还有一个自定义的JwtAuthenticationFilter,它从AbstractAuthenticationProcessingFilter 扩展为身份验证阶段的一部分,因此我还在此类过滤器中放置了一个断点并检查链。在那里我看到了 originalChain(之前评论过的ApplicationFilterChain)和“additionalFilters”集合,其中出现了我的JwtAuthenticationFilter 以及弹簧安全过滤器。但是它们都没有 asyncSupported 属性,所以我假设它们不是开发服务器抛出的错误的一部分。请注意,正如我在本地提到的,一切正常;该错误只是在部署到开发服务器时出现。
控制器方法:
@GetMapping(path = "/export")
public Callable<ResponseEntity> exportData() throws IOException {
return new CustomContextAwareCallable(() -> handleResponse());
}
所以我的问题是:即使 ApplicationFilterChain 上的每个过滤器以及 servlet 的 asyncSupported 为 true,为什么我会在部署后从服务器收到上面显示的错误?
该应用程序没有在服务器上部署为 .WAR,它只是使用嵌入式 tomcat(我在本地做的相同)。
更新:另一个区别是在开发环境中客户端请求通过 nginx 代理(只是想知道是否由于某种原因请求属性 org.apache.catalina.ASYNC_SUPPORTED 可以修改为假(在本地它是真的)。
有什么想法吗?
【问题讨论】:
-
@UsamaAmjad 是的,我刚刚记录了请求期间 ApplicationFilterChain 上存在的所有过滤器,并且所有过滤器都支持异步(可以通过使用 ((ApplicationFilterChain)chain).findNonAsyncFilters(nonAsyncFilters);在组成链的任何过滤器中的 doFilter 方法中)。因此,由于所有过滤器及其 serlvet 都支持异步;我怀疑将tomcat设置请求属性org.apache.catalina.ASYNC_SUPPORTED设置为false(但仍然不知道为什么)。
标签: spring spring-mvc servlet-filters callable