I have a problem with Spring Boot configuration. I got exception on some mobile devices which should use sockets:
java.lang.IllegalArgumentException: Async s
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 \"true \" 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:
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);
}
}