当前位置: 首页 > 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.jsqmd.com/news/996093/

相关文章:

  • 2026年新发布针织衫品牌厂商有哪些?实力工厂的选型与推荐 - 品牌鉴赏官2026
  • 避开OV5640时钟配置的坑:PCLK计算不准导致图像异常的排查与修复指南
  • ComfyUI-LTXVideo:零基础到专业级AI视频生成的终极指南
  • OpenClaw+AWS 深度应用:自动生成 CloudFormation 模板、批量管理 S3 存储桶
  • 如何在Obsidian中构建你的微信读书知识库:终极同步指南
  • 第31篇:AI时代的前端工作流
  • Vivado Utility Buffer IP全解析:从IBUFDS到BUFGCE,手把手教你时钟与IO缓冲器选型
  • 保姆级教程:用STM32的MPU为你的AUTOSAR应用划清内存“地盘”(附代码)
  • 不止看功耗:Vivado里Report RAM和Control Sets的隐藏用法与优化技巧
  • Go 微服务 Saga 模式:分布式事务的补偿与一致性实践
  • 3D大模型位置编码:C2RoPE的创新与突破
  • 2026年6月东莞制造业升级,3M VHB GPL160平台选择全攻略 - 品牌鉴赏官2026
  • 5分钟掌握PKHeX自动合法性插件:让宝可梦数据合规变得简单
  • 5分钟快速上手:免费开源的暗黑破坏神2存档编辑器完整指南
  • 北邮网络课设:VC6.0下用select实现的轻量级DNS中继服务源码包
  • 如何用foobox三分钟打造专业音乐播放器:foobar2000终极美化指南
  • 2026年球场护栏网安装厂家怎么选?四川及全国主流服务商综合分析与案例参考 - 优质品牌商家
  • 别再为测正负电压发愁了!手把手教你用LTspice仿真两种绝对值电路(附ADA4522/LT1001实测对比)
  • 【趣味算法】韩信点兵:从枚举到中国剩余定理(附多语言源码)
  • 别再说佳明不准了!手把手教你校准fēnix 7X心率,搞定极限运动数据漂移
  • 从SPI到QSPI:当你的SD卡和Flash嫌SPI太慢时,我们该怎么办?
  • 给3DGS/NeRF新手的球面谐波(SH)极简图解:从‘外星生物’到‘颜色魔法’
  • 新手也能懂:手把手带你逆向分析一个CrackMe程序(附注册机C++源码)
  • Mermaid Live Editor终极指南:5分钟掌握实时图表编辑神器
  • 地下水耦合建模全景解析暨SWAT-MODFLOW地表与地下协同模拟及多情景专题应用
  • 如何利用7zip批量测试功能快速恢复加密压缩包访问权限:ArchivePasswordTestTool完整指南
  • 3大实战场景!用Buzz离线音频转写工具彻底改变你的音频处理方式
  • Python 高手编程系列三千四百三十五 :Hy
  • EFI Boot Editor:终极UEFI启动管理工具完整指南
  • 突破游戏资源编辑壁垒:Harepacker-resurrected一站式解决方案深度解析