当前位置: 首页 > news >正文

Spring Boot 实现过滤器(Filter)三种常用方式

Filter 是 Java Web 原生组件,优先级早于 Interceptor,可拦截所有请求,下面分三种主流实现方式,附完整代码、配置、执行顺序。

一、前置说明

  • 过滤器基于javax.servlet.Filter(Servlet 规范)
  • 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(filterName="MyFilter",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,扫描@WebFilter

importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.boot.web.servlet.ServletComponentScan;@SpringBootApplication@ServletComponentScan// 关键注解:扫描 Servlet、Filter、ListenerpublicclassDemoApplication{publicstaticvoidmain(String[]args){SpringApplication.run(DemoApplication.class,args);}}

优缺点

  • ✅ 简单快捷,适合单过滤器、简单项目
  • 无法手动指定多个过滤器执行顺序

方式二:注册 FilterRegistrationBean(推荐,可控制顺序)

Spring Boot 官方推荐方式,支持排序、指定拦截路径、禁用原生注解,多过滤器首选。

1. 先写过滤器(普通 Java 类,不加 @WebFilter)

importjavax.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{@BeanpublicFilterRegistrationBean<OrderFilter1>filter1(){FilterRegistrationBean<OrderFilter1>bean=newFilterRegistrationBean<>();bean.setFilter(newOrderFilter1());bean.addUrlPatterns("/*");// 拦截路径bean.setOrder(1);// 执行顺序:1 > 2returnbean;}@BeanpublicFilterRegistrationBean<OrderFilter2>filter2(){FilterRegistrationBean<OrderFilter2>bean=newFilterRegistrationBean<>();bean.setFilter(newOrderFilter2());bean.addUrlPatterns("/*");bean.setOrder(2);// 顺序靠后returnbean;}}

执行顺序

请求进来:Filter1 → Filter2 → 接口 → Filter2后置 → Filter1后置

常用配置扩展

// 排除指定路径bean.addInitParameter("exclusions","/login,/static/*");// 设置过滤器名称bean.setName("customFilter");

方式三:直接将 Filter 交给 Spring 容器(简单排序)

直接在 Filter 上加@Component,Spring 自动注册为过滤器。

代码示例

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(数值)数值越小越先执行

@Component@Order(0)publicclassBeanFilter1implementsFilter{...}@Component@Order(1)publicclassBeanFilter2implementsFilter{...}

优缺点

  • ✅ 写法简洁
  • ❌ 部分场景路径配置不如FilterRegistrationBean灵活

四、常见实战场景示例(跨域、编码)

统一编码过滤器

@ComponentpublicclassEncodingFilterimplementsFilter{@OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-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);}}

五、三种方式总结 & 选型建议

  1. 简单单过滤器:用@WebFilter + @ServletComponentScan
  2. 多过滤器、需要严格排序/精细路径配置:优先FilterRegistrationBean(企业常用)
  3. 快速开发、简单排序@Component + @Order

注意:Filter 无法获取 Spring MVC 的Controller 方法信息,如需拦截接口、获取注解/方法参数,改用Interceptor 拦截器

http://www.zskr.cn/news/1507859.html

相关文章:

  • 避开OV5640时钟配置的坑:PCLK计算不准导致图像异常的排查与修复指南
  • 第31篇:AI时代的前端工作流
  • 保姆级教程:用STM32的MPU为你的AUTOSAR应用划清内存“地盘”(附代码)
  • 2026年6月东莞制造业升级,3M VHB GPL160平台选择全攻略 - 品牌鉴赏官2026
  • 北邮网络课设:VC6.0下用select实现的轻量级DNS中继服务源码包
  • 2026年球场护栏网安装厂家怎么选?四川及全国主流服务商综合分析与案例参考 - 优质品牌商家
  • 别再说佳明不准了!手把手教你校准fēnix 7X心率,搞定极限运动数据漂移
  • 如何用foobox三分钟打造专业音乐播放器:foobar2000终极美化指南
  • 3大实战场景!用Buzz离线音频转写工具彻底改变你的音频处理方式
  • Java开发者的效率工具箱:提升编码速度的秘诀
  • DC-DC模块电源的FB引脚,除了调压还能怎么玩?一个运放电路带来的新思路
  • 深入PHY6222蓝牙协议栈:从simpleBLEPeripheral看GATT属性表的组织与交互逻辑
  • 实践:Triton Inference Server 吞吐量优化全解析
  • 告别手动录入:用Java+海康SDK实现明眸门禁人员信息自动同步(Spring Boot项目集成)
  • YTSage YouTube下载器详解
  • 从ICL7107到现代万用表:拆解一块老式数字表,聊聊模拟前端设计的演进
  • 5步完成低显存AI模型部署:24GB以下显卡实战指南
  • AI驱动的流域水–碳–氮多过程耦合模拟
  • 从“比例读数”到“真有效值”:聊聊ICL7107老芯片在万用表设计中的那些经典电路变种
  • 别再为OsgEarth加载天地图发愁了!手把手教你封装C++工具类(附完整源码)
  • 金色传说:SAP-SD-VF051科目确定报错深度排查与实战修复
  • Vehicle outbound
  • 2026图片去水印工具怎么选?免费电脑手机在线靠谱无广告软件推荐
  • 不只是空气和水:格子玻尔兹曼方法(LBM)在电池散热与芯片设计中的实战案例拆解
  • 终极指南:3分钟打造你的专属iTerm2终端配色方案
  • 从“策略指纹”到模仿学习:占用度量如何成为连接理论与实践的桥梁?
  • 从PHP 5到PHP 8:??运算符的演进与?:的经典用法全解析
  • ESP32S3日志打印不全?排查Channel for console output配置(USB/串口模式详解)
  • 2026年德阳四川EPP泡沫包装市场格局:本地供应商实力与案例深度分析 - 优质品牌商家
  • 2026杭州音乐艺考培训机构深度分析:老牌名校与新锐力量谁更值得选择? - 优质品牌商家