Spring Boot控制器用Callable异步处理请求报错:需开启Servlet及Filter异步支持
Hey there! Let me walk you through fixing that frustrating async support error you're hitting when using Callable to free up servlet threads in your Spring Boot controller.
Why This Happens
When you return a Callable from a controller method, Spring tries to handle the request asynchronously—meaning it releases the servlet thread while your long-running task executes in the background. But your servlet container (like Tomcat) throws this error because it doesn't have async support enabled for either the main DispatcherServlet or one of the filters involved in processing the request.
Quick Fix: Use Spring Boot Configuration Files
For most Spring Boot 2.x+ applications, the easiest way to ensure async support is enabled is by adding a few properties to your application.properties or application.yml:
application.properties
# Optional: Set a timeout for async requests (in milliseconds) spring.mvc.async.request-timeout=30000
Spring Boot enables async support for the DispatcherServlet by default in recent versions, but adding this property ensures the async setup is properly configured. If you still see the error after this, you likely have a custom filter or servlet that's missing async support.
Fix for Custom Servlets/Filters
If you've defined custom servlets or filters in your application, you need to explicitly enable async support for each one involved in async request processing.
1. Enable Async for DispatcherServlet (if customizing it)
If you've overridden the default DispatcherServlet, make sure to set asyncSupported=true:
@Configuration public class WebConfig { @Bean public DispatcherServlet dispatcherServlet() { DispatcherServlet dispatcherServlet = new DispatcherServlet(); dispatcherServlet.setAsyncSupported(true); // Critical line dispatcherServlet.setDispatchOptionsRequest(true); return dispatcherServlet; } }
2. Enable Async for Custom Filters
Every filter that touches async requests (including third-party filters you've added) needs to have async support enabled. Use FilterRegistrationBean to configure this:
@Bean public FilterRegistrationBean<MyCustomFilter> myCustomFilterRegistration() { FilterRegistrationBean<MyCustomFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new MyCustomFilter()); registrationBean.addUrlPatterns("/*"); registrationBean.setAsyncSupported(true); // Critical line return registrationBean; }
Key Reminder
Double-check all filters in your application (even ones from dependencies like security or logging filters). If any filter doesn't have asyncSupported=true, it will block async request processing and throw the same error.
Once you've applied these changes, restart your application and test your Callable controller method again—it should now handle async requests properly and free up those servlet threads!
内容的提问来源于stack exchange,提问作者emarichal

