Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 弹簧启动启用<;支持异步>;就像在web.xml中一样_Java_Spring_Spring Mvc_Spring Boot - Fatal编程技术网

Java 弹簧启动启用<;支持异步>;就像在web.xml中一样

Java 弹簧启动启用<;支持异步>;就像在web.xml中一样,java,spring,spring-mvc,spring-boot,Java,Spring,Spring Mvc,Spring Boot,我对Spring引导配置有问题。我在一些应该使用套接字的移动设备上遇到异常: 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 adding "<async-su

我对Spring引导配置有问题。我在一些应该使用套接字的移动设备上遇到异常:

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 adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml. Also you must use a Servlet 3.0+ container
    at org.springframework.util.Assert.isTrue(Assert.java:65)
    at org.springframework.http.server.ServletServerHttpAsyncRequestControl.<init>(ServletServerHttpAsyncRequestControl.java:59)
    at org.springframework.http.server.ServletServerHttpRequest.getAsyncRequestControl(ServletServerHttpRequest.java:202)
    at org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession.handleInitialRequest(AbstractHttpSockJsSession.java:202)
    at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportHandler.handleRequestInternal(AbstractHttpSendingTransportHandler.java:66)
    at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportHandler.handleRequest(AbstractHttpSendingTransportHandler.java:58)
    at org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService.handleTransportRequest(TransportHandlingSockJsService.java:254)
    at org.springframework.web.socket.sockjs.support.AbstractSockJsService.handleRequest(AbstractSockJsService.java:322)
    at org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler.handleRequest(SockJsHttpRequestHandler.java:88)
    at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    ...
java.lang.IllegalArgumentException:必须在servlet和异步请求处理中涉及的所有筛选器上启用异步支持。这是在Java代码中使用Servlet API完成的,或者通过向Servlet添加“true”并在web.xml中过滤声明来完成的。您还必须使用Servlet 3.0+容器
位于org.springframework.util.Assert.isTrue(Assert.java:65)
位于org.springframework.http.server.ServletServerHttpAsyncRequestControl。(ServletServerHttpAsyncRequestControl.java:59)
位于org.springframework.http.server.ServletServerHttpRequest.getAsyncRequestControl(ServletServerHttpRequest.java:202)
位于org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession.handleInitialRequest(AbstractHttpSockJsSession.java:202)
位于org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportorHandler.HandlerRequestInternal(AbstractHttpSendingTransportorHandler.java:66)
位于org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportorHandler.HandlerRequest(AbstractHttpSendingTransportorHandler.java:58)
位于org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService.HandletTransportRequest(TransportHandlingSockJsService.java:254)
位于org.springframework.web.socket.sockjs.support.AbstractSockJsService.HandlerRequest(AbstractSockJsService.java:322)
位于org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler.handleRequest(SockJsHttpRequestHandler.java:88)
位于org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51)
位于org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
位于org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
位于org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
位于org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
位于javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
位于org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
位于javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
...
从异常中可以看出,我必须通过在web.xml文件中添加true来启用异步处理。但这就是问题所在,因为我没有它——我们的项目使用SpringBoot


有没有办法像Spring Boot那样提供相同的功能?

您只需要定义
dispatcherServlet
@Bean

@Bean
public ServletRegistrationBean dispatcherServlet() {
    ServletRegistrationBean registration = new ServletRegistrationBean(
            new DispatcherServlet(), "/");
    registration.setAsyncSupported(true);
    return registration;
}

它覆盖了DispatcherServletAutoConfiguration中的默认配置,可能值得一提的是Spring Boot默认为DispatcherServlet和所有过滤器启用了异步支持

引自:

我们自动将async supported设置为true 因为DispatcherServlet知道如何处理这些请求和 基本上是由各个控制器方法返回某些内容 就像一个推迟的结果。此外,我们还为 任何过滤器(通过getServletFilters提供)以及设置 要包含异步的每个筛选器的DispatcherType


至少我的实践证明了这一点

即使我在晚会上迟到了,我还是要为后代发布我的工作方案

我也面临同样的问题,并尝试了@Artem Bilan提出的解决方案。但是在调试代码之后,我知道
servletRegistrationBean.isAsyncSupported()
默认情况下是
true

代码块生成的实际错误来自方法
org.springframework.web.context.request.async.StandardServletAsyncWebRequest.startAsync()
,当
getRequest().isAsyncSupported()
false
时,我们会收到此错误。尽管
ServletRegistrationBean#asyncSupported
值为
true
HttpServletRequest#isAsyncSupported()
方法值对于所有API请求始终设置为
false

代码块的执行

虽然没有明确的答案,但我已经为这个问题实现了一个变通方法。要总结所有需要的更改,如下所示:

  • 添加筛选器以将请求属性设置为
    request.setAttribute(Globals.ASYNC\u SUPPORTED\u ATTR,true)
  • 将筛选器添加到您的筛选器链中,在我的示例中,我已将我的筛选器注册到spring上下文中,如下所示

  • 这种做法包括在tomcat上部署Spring应用程序而不是独立应用程序吗?@Antoniosss我的答案是在将monolith Spring(不是Spring boot)应用程序迁移到一组独立Spring boot服务的过程中得出的。据我记忆所及,以前的单片非spring引导版本的应用程序必须启用显式支持的异步。事实证明并非如此。spring引导中的行为发生了变化?上述声明是由Spring Boot的作者在2014年发表的……我也这么说了,但这并不是胡编乱造的。我们必须在某个地方通过类似@EnableAsync的东西-记不清了,但这是一个单一注释的问题(乍一看与此无关)。我使用了这个过滤器,它解决了我的问题。注意,我没有将过滤器添加到过滤器链中。Spring正在自动处理这个问题。
    Assert.state(getRequest().isAsyncSupported(),
                    "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 adding \"<async-supported>true</async-supported>\" to servlet and " +
                    "filter declarations in web.xml.");
    
    
    specialAttributes.put(Globals.ASYNC_SUPPORTED_ATTR,
                    new SpecialAttributeAdapter() {
                        @Override
                        public Object get(Request request, String name) {
                            return request.asyncSupported;
                        }
    
                        @Override
                        public void set(Request request, String name, Object value) {
                            Boolean oldValue = request.asyncSupported;
                            request.asyncSupported = (Boolean)value;
                            request.notifyAttributeAssigned(name, value, oldValue);
                        }
                    });
    
    
    
    @Component
    public class AsyncSupportFilter extends OncePerRequestFilter {
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
            request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, true);
            chain.doFilter(request, response);
        }
    }
    
    
    
    @Component
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
       @Autowired
       private AsyncSupportFilter asyncSupportFilter = null;
       @Override
       public void configure(HttpSecurity httpSecurity) {
    
           httpSecurity.addFilter(asyncSupportFilter);
           // we can add the filter before any filter like as httpSecurity.addFilterBefore(asyncSupportFilter , BasicAuthenticationFilter.class);
       }
    }