当我的SpringBoot应用程序从可执行JAR运行时,下面显示的以下REST端点可以按预期工作。即,它将文本“我的测试响应”返回给客户端。但是,当我打包与WAR相同的应用程序并部署到Tomcat(8.0.29)时,它将引发以下异常:
发生意外错误(类型=内部服务器错误,状态= 500)。必须在Servlet上以及对异步请求处理中涉及的所有过滤器启用异步支持。这是通过Java代码使用Servlet API或通过在Web.xml中的Servlet和过滤器声明中添加“ true”来完成的。
package my.rest.controllers;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
@RestController
@RequestMapping("/api/file")
public class FileContentRestController {
static final int BUFFER = 2048;
@RequestMapping(value = "/content", method = RequestMethod.GET)
@ResponseBody
public StreamingResponseBody getFileContent(HttpServletResponse response) {
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
final InputStream portalFileStream = new ByteArrayInputStream("My test response".getBytes());
return (OutputStream outputStream) -> {
int n;
byte[] buffer = new byte[1024];
while ((n = portalFileStream.read(buffer)) > -1) {
outputStream.write(buffer, 0, …Run Code Online (Sandbox Code Playgroud) 我使用带有websocket支持的spring 4.0.3,我的websocket的spring配置是:
<websocket:message-broker application-destination-prefix="/kiford">
<websocket:stomp-endpoint path="/websocket">
<websocket:sockjs/>
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/queue, /topic"/>
</websocket:message-broker>
Run Code Online (Sandbox Code Playgroud)
当我的客户端连接到服务器时:
this.socket = new SockJS('websocket/');
this.client = Stomp.over(this.socket);
this.client.connect({}, success_callback, error_callback);
Run Code Online (Sandbox Code Playgroud)
spring的控制台打印了以下错误消息:
2014-05-27 18:22:46.410 [http-apr-8080-exec-5] DEBUG c.k.b.c.SystemExceptionResolver[41] - #????[/kiford-server-1.3/websocket/996/6fodvwrl/eventsource]??????????
org.springframework.web.socket.sockjs.SockJsException: Uncaught failure in SockJS request, uri=http://localhost:8080/kiford-server-1.3/websocket/996/6fodvwrl/eventsource; nested exception is org.springframework.web.socket.sockjs.SockJsException: Uncaught failure for request http://localhost:8080/kiford-server-1.3/websocket/996/6fodvwrl/eventsource; nested exception is java.lang.IllegalArgumentException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by …Run Code Online (Sandbox Code Playgroud) 我尝试在控制器中使用返回类型 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 代理传递(只是想知道是否由于某种原因请求属性 …
spring ×2
callable ×1
java ×1
servlet-3.0 ×1
sockjs ×1
spring-boot ×1
spring-mvc ×1
war ×1
websocket ×1