相关疑难解决方法(0)

如何在打包和部署为WAR的Springboot应用程序中启用异步支持

当我的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)

java war servlet-3.0 spring-boot

5
推荐指数
1
解决办法
5482
查看次数

当websocket客户端连接到服务器时出现SockJsException

我使用带有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)

spring websocket sockjs

4
推荐指数
1
解决办法
5799
查看次数

IllegalStateException:必须在 servlet 和所有过滤器上启用异步支持

我尝试在控制器中使用返回类型 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 spring-mvc callable servlet-filters

1
推荐指数
1
解决办法
3662
查看次数