问题前景
在使用SpringBoot结合Stomp操作WebSocket时,本地Win11环境下没有出现问题,上了服务器前端连接WebSocket时就报了这么一个问题:
Async support must be enabled on a servlet and for all filters involved in async request processing
解决方案
主要就是添加过滤器解决这个问题
使用SpringSecurity的情况
如果项目中使用到了SpringSecurity,那就添加Security相关的过滤器,因为Security的过滤器默认情况下会优先比MVC的过滤器早执行
package com.mahjong.filter; import org.apache.catalina.Globals; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @Author: 资深高级Java开发工程师 * @CreateDate: 2023/3/19 * @Description: 配置WebSocket异步支持过滤器,解决服务器异常:Async support must be enabled on a servlet and for all filters involved in async request processing */ public class AsyncSupportFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR,true); filterChain.doFilter(request,response); } }
然后需要讲该过滤器注册到Security的过滤器链中
/** * @Author: 资深高级Java开发工程师 * @CreateDate: 2023/3/19 * @Description: web应用安全配置类 */ @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { //注册到Security的过滤器链中,如果还有其他的Security的过滤器,那么AsyncSupportFilter过滤器一定要写在它们的前面 http.addFilterBefore(new AsyncSupportFilter(), UsernamePasswordAuthenticationFilter.class); } }
不使用SpringSecurity的情况
不使用SpringSecurity的情况下我们只需要声明一个MVC相关的过滤器即可,并且设置过滤器的优先级为最早执行即可
/** * @Author: 资深高级Java开发工程师 * @CreateDate: 2023/3/19 * @Description: IP限制过滤器 */ @Order(Integer.MIN_VALUE)//设置优先级为int的最小值 //asyncSupported = true这个属性是解决问题的关键 @WebFilter(urlPatterns = "/*",filterName = "AsyncSupportFilter",asyncSupported = true) @Component public class AsyncSupportFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //保险期间还是加了这个配置,但是好像不加也可以的,具体的大家可以去试试看不加行不行 request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, true); chain.doFilter(request, response); } }