添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have a problem with Spring Boot configuration. I got exception on some mobile devices which should use sockets:

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)

As I see from the exception, I have to enable async processing by adding true into the web.xml file. But this is the problem because I don't have it - our project uses Spring Boot.

Is there any way to provide the same functionality in Spring Boot like does?

You just need to define dispatcherServlet @Bean:

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

It overrides that default one from DispatcherServletAutoConfiguration.

If it complains about raw types, write ServletRegistrationBean<DispatcherServlet> instead of ServletRegistrationBean. – Florian F Apr 9 at 21:01 Or just DispatcherServletRegistrationBean. At the time I wrote this answer there was no that generic type on the ServletRegistrationBean. – Artem Bilan Apr 10 at 13:13

Even though I am late to the party I am posting my working solution for posterity.

I had faced the same issue and tried the solution suggested by @Artem Bilan. But after debugging the code, I came to know that the servletRegistrationBean.isAsyncSupported() is by default true.

The actual error is being generated by the code block is from the method org.springframework.web.context.request.async.StandardServletAsyncWebRequest.startAsync() and we are getting this error when getRequest().isAsyncSupported() is false. Despite the ServletRegistrationBean#asyncSupported value is true, HttpServletRequest#isAsyncSupported() method value is always set to false for all API requests.

The Exerpt of the code block Code Reference

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.");

When analyzing further, I came to know that requestAttributes -> Globals.ASYNC_SUPPORTED_ATTR decides whether the request has to be processed in an Async way or not.

During the normal scenario, the requests do not have Globals.ASYNC_SUPPORTED_ATTR requestAttribute, hence request.asyncSupported will be false, if we manually add that requestAttribute ASYNC_SUPPORTED_ATTR value as true for all the requests using something like filters then request#asyncSupported value will be set to true as per the below code block Code Reference

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);

Though there is no explicit answer, I have implemented a workaround for this issue. To Summarize all the required changes are listed below:

  • Add a filter to set the request attribute as request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, true)
  • @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); I used this filter and it solved my problem. Note that, I didn't add the filter into the filter chain. Spring is handling that automatically. – Halil Jul 24, 2020 at 19:31

    Maybe it worth to mention that Spring Boot has async-support enabled by default for dispatcher servlet and all filters

    Quotation from github:

    We automatically set async-supported to true because the DispatcherServlet knows how to work with such requests and it's basically up to individual controller methods to return something like a DeferredResult. Furthermore, we also set async-supported for any filter (provided via getServletFilters) along with setting the DispatcherType for each filter to include ASYNC.

    At least my practice supports this statement

    @Antoniossss that my answer was made during a migration project of a monolith spring (not spring boot) application to a set of standalone spring boot services. Previous, monolithic, non-spring boot version of the app had to turn on async-supported explicitly as far as I remember. – AlexK Feb 6, 2020 at 3:55 The behavior has changed in Spring Boot? The abovementioned statement was made by Spring Boot authors in 2014..... – AlexK Feb 6, 2020 at 13:30 I say it too but too but it was just not wrorking. We had to ass something like @EnableAsync somewhere - cannot remember exactly, but it was a matter of singe annotation (that does not relates to this at first glance) – Antoniossss Feb 6, 2020 at 14:07
    @WebFilter(value = {"/subscriberinfo/query/single/*"}, asyncSupported = true)
    public class ...Filter{
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.