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
.
–
–
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);
–
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
–
–
–
@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.