Spring Boot 实现过滤器(Filter)三种常用方式
Filter 是 Java Web 原生组件优先级早于 Interceptor可拦截所有请求下面分三种主流实现方式附完整代码、配置、执行顺序。一、前置说明过滤器基于javax.servlet.FilterServlet 规范Spring Boot 无需手动配置web.xml注解/注册 Bean即可生效执行顺序Filter → DispatcherServlet → Interceptor → Controller方式一注解方式最简推荐简单场景使用WebFilter 启动类开启 Servlet 注解扫描零配置。1. 编写自定义过滤器importjavax.servlet.*;importjavax.servlet.annotation.WebFilter;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;// 拦截所有请求 /*WebFilter(filterNameMyFilter,urlPatterns/*)publicclassMyFilterimplementsFilter{// 初始化容器启动执行一次Overridepublicvoidinit(FilterConfigfilterConfig)throwsServletException{System.out.println(过滤器初始化);}// 核心拦截逻辑每次请求都会执行OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{HttpServletRequestreq(HttpServletRequest)request;HttpServletResponseresp(HttpServletResponse)response;// 放行前逻辑前置处理System.out.println(请求地址req.getRequestURI());// 放行执行后续过滤器/接口chain.doFilter(request,response);// 放行后逻辑后置处理响应返回客户端前System.out.println(请求结束);}// 销毁容器关闭执行一次Overridepublicvoiddestroy(){System.out.println(过滤器销毁);}}2. 启动类开启注解支持启动类添加ServletComponentScan扫描WebFilterimportorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.boot.web.servlet.ServletComponentScan;SpringBootApplicationServletComponentScan// 关键注解扫描 Servlet、Filter、ListenerpublicclassDemoApplication{publicstaticvoidmain(String[]args){SpringApplication.run(DemoApplication.class,args);}}优缺点✅ 简单快捷适合单过滤器、简单项目❌无法手动指定多个过滤器执行顺序方式二注册 FilterRegistrationBean推荐可控制顺序Spring Boot 官方推荐方式支持排序、指定拦截路径、禁用原生注解多过滤器首选。1. 先写过滤器普通 Java 类不加 WebFilterimportjavax.servlet.*;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;publicclassOrderFilter1implementsFilter{OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{System.out.println(【过滤器1】执行);chain.doFilter(request,response);System.out.println(【过滤器1】结束);}Overridepublicvoidinit(FilterConfigfilterConfig){}Overridepublicvoiddestroy(){}}publicclassOrderFilter2implementsFilter{OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{System.out.println(【过滤器2】执行);chain.doFilter(request,response);System.out.println(【过滤器2】结束);}Overridepublicvoidinit(FilterConfigfilterConfig){}Overridepublicvoiddestroy(){}}2. 编写配置类注册过滤器 排序order值越小优先级越高越先执行。importorg.springframework.boot.web.servlet.FilterRegistrationBean;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;ConfigurationpublicclassFilterConfig{BeanpublicFilterRegistrationBeanOrderFilter1filter1(){FilterRegistrationBeanOrderFilter1beannewFilterRegistrationBean();bean.setFilter(newOrderFilter1());bean.addUrlPatterns(/*);// 拦截路径bean.setOrder(1);// 执行顺序1 2returnbean;}BeanpublicFilterRegistrationBeanOrderFilter2filter2(){FilterRegistrationBeanOrderFilter2beannewFilterRegistrationBean();bean.setFilter(newOrderFilter2());bean.addUrlPatterns(/*);bean.setOrder(2);// 顺序靠后returnbean;}}执行顺序请求进来Filter1 → Filter2 → 接口 → Filter2后置 → Filter1后置常用配置扩展// 排除指定路径bean.addInitParameter(exclusions,/login,/static/*);// 设置过滤器名称bean.setName(customFilter);方式三直接将 Filter 交给 Spring 容器简单排序直接在 Filter 上加ComponentSpring 自动注册为过滤器。代码示例importorg.springframework.stereotype.Component;importjavax.servlet.*;importjava.io.IOException;ComponentpublicclassBeanFilterimplementsFilter{OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{System.out.println(Spring Bean 过滤器执行);chain.doFilter(request,response);}Overridepublicvoidinit(FilterConfigfilterConfig){}Overridepublicvoiddestroy(){}}控制顺序配合Order(数值)数值越小越先执行ComponentOrder(0)publicclassBeanFilter1implementsFilter{...}ComponentOrder(1)publicclassBeanFilter2implementsFilter{...}优缺点✅ 写法简洁❌ 部分场景路径配置不如FilterRegistrationBean灵活四、常见实战场景示例跨域、编码统一编码过滤器ComponentpublicclassEncodingFilterimplementsFilter{OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{request.setCharacterEncoding(UTF-8);response.setContentType(text/html;charsetUTF-8);chain.doFilter(request,response);}}简单跨域过滤器ComponentpublicclassCorsFilterimplementsFilter{OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{HttpServletResponseresp(HttpServletResponse)response;resp.setHeader(Access-Control-Allow-Origin,*);resp.setHeader(Access-Control-Allow-Methods,GET,POST,PUT,DELETE);resp.setHeader(Access-Control-Max-Age,3600);resp.setHeader(Access-Control-Allow-Headers,*);chain.doFilter(request,response);}}五、三种方式总结 选型建议简单单过滤器用WebFilter ServletComponentScan多过滤器、需要严格排序/精细路径配置优先FilterRegistrationBean企业常用快速开发、简单排序Component Order注意Filter 无法获取 Spring MVC 的Controller 方法信息如需拦截接口、获取注解/方法参数改用Interceptor 拦截器。