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

Springboot 项目中使用 Filter 全指南

目录

一、Filter与Interceptor有什么区别

二、Filter接口

三、使用方法

3.1 使用@WebFilter注解方式

3.2 使用FilterRegistrationBean配置方式

3.3  使用DelegatingFilterProxy方式

四、Filter的典型应用场景

4.1 权限验证​​

4.2 跨域处理​​:设置CORS相关响应头

4.3 日志记录​​:记录请求信息、处理时间等

4.4 ​​编码设置​​:统一设置请求和响应的编码

五、最佳实践建议


一、Filter与Interceptor有什么区别

Filter(过滤器)​​是Servlet规范(J2EE标准)定义的组件,基于Servlet容器(如Tomcat)的回调机制实现。它不依赖于任何特定框架,可以在任何Java Web工程中使用,通过实现javax.servlet.Filter接口来定义。

Filter的工作层级处于Servlet容器层面,能够拦截进入容器的所有请求包括静态资源(HTML/CSS/JS等)。

​Interceptor(拦截器)​​是Spring MVC框架提供的机制,基于Java反射和动态代理技术实现。它必须依赖Spring框架环境,通过实现HandlerInterceptor接口来定义。Interceptor工作在框架层面,只能拦截Spring MVC处理的Controller请求无法拦截静态资源请求

特性

Filter

Interceptor

规范

Servlet规范

Spring框架提供

拦截范围

所有资源(包括静态资源)

只拦截Controller方法

执行位置

Servlet之前执行

Controller方法前后执行

依赖关系

不依赖Spring容器

是Spring的一部分

配置方式

web.xml或@WebFilter或注入Bean

实现HandlerInterceptor接口

二、Filter接口

Filter接口

package javax.servlet;import java.io.IOException;public interface Filter {public default void init(FilterConfig filterConfig) throws ServletException {}public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException;public default void destroy() {}
}

三、使用方法

3.1 使用@WebFilter注解方式

@WebFilter(filterName = "myFilter", urlPatterns = "/*")
public class MyFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {// 请求预处理逻辑System.out.println("进入MyFilter过滤器");// 放行请求chain.doFilter(request, response);// 响应后处理逻辑}}

注意​​:使用 @WebFilter 需要在启动类上添加@ServletComponentScan注解

@SpringBootApplication
@ServletComponentScan
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

这种方式的特点是:

  • 配置简单,直接在Filter类上使用注解

  • 执行顺序由Filter类名的字母顺序决定,无法自定义

  • 适合简单的单过滤器场景

3.2 使用FilterRegistrationBean配置方式

这是更灵活的方式,可以精确控制过滤器的顺序和拦截规则

@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<MyFilter> otherRegistration() {FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>();registration.setFilter(new MyFilter());// 添加过滤路径(只对路径过滤)registration.addUrlPatterns("/user");// 设置执行顺序,数字越小优先级越高registration.setOrder(2);// 设置过滤器名称registration.setName("myFilter");return registration;}@Beanpublic FilterRegistrationBean<MyFilter2> myFilterRegistration() {FilterRegistrationBean<MyFilter2> registration = new FilterRegistrationBean<>();registration.setFilter(new MyFilter2());// 添加过滤路径(只对路径过滤)registration.addUrlPatterns("/*");// 设置执行顺序,数字越小优先级越高registration.setOrder(1);// 设置过滤器名称registration.setName("myFilter2");return registration;}
}

这种方式的特点是:

  • 可以精确控制过滤器的执行顺序

  • 可以配置多个URL模式

  • 适合需要多个过滤器且有顺序要求的场景

  • 可以在Filter中注入Spring管理的Bean(需要将Filter也声明为Bean)

3.3  使用DelegatingFilterProxy方式

@Component
public class MySpringFilter implements Filter {// 可以在这里注入Spring管理的Bean@Autowiredprivate SomeService someService;@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {// 使用注入的BeansomeService.doSomething();chain.doFilter(request, response);}
}
@Component
public class HtFilter implements Filter {@Autowiredprivate ExcelImportService excelImportService;@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {String test = excelImportService.getTest();System.out.println("HT 过滤器" + test);}
}
@Configuration
public class FilterConfig2 {@Beanpublic DelegatingFilterProxyRegistrationBean delegatingFilterProxy() {DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean("mySpringFilter ");registration.addUrlPatterns("/*");registration.setOrder(1);return registration;}@Beanpublic DelegatingFilterProxyRegistrationBean delegatingFilterProxy2() {DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean("htFilter");registration.addUrlPatterns("/user");registration.setOrder(2);return registration;}
}

 

说明

避免混合使用不同配置方式,防止出现异常!

doFilter()方法中,必须调用chain.doFilter(request, response)来放行请求,否则请求会被阻断。

四、Filter的典型应用场景

4.1 权限验证​

检查用户是否登录或是否有权限访问资源

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;HttpSession session = req.getSession();if(session.getAttribute("user") == null) {// 用户未登录,返回错误或重定向(前后端分离项目一般不用重定向而是选择返回错误json即可)HttpServletResponse resp = (HttpServletResponse) response;resp.sendRedirect("/login");return;}chain.doFilter(request, response);
}

4.2 跨域处理​​:设置CORS相关响应头

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletResponse resp = (HttpServletResponse) response;resp.setHeader("Access-Control-Allow-Origin", "*");resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");resp.setHeader("Access-Control-Max-Age", "3600");resp.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");chain.doFilter(request, response);
}

4.3 日志记录​​:记录请求信息、处理时间等

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {long startTime = System.currentTimeMillis();HttpServletRequest req = (HttpServletRequest) request;String requestURI = req.getRequestURI();chain.doFilter(request, response);long elapsed = System.currentTimeMillis() - startTime;System.out.println("请求"+requestURI+"处理时间:"+elapsed+"ms");
}

4.4 ​​编码设置​​:统一设置请求和响应的编码

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");response.setCharacterEncoding("UTF-8");chain.doFilter(request, response);
}

五、最佳实践建议

  1. ​简单场景​​:使用@WebFilter + @ServletComponentScan方式

  2. ​复杂场景​​:使用FilterRegistrationBean方式,可以更好控制顺序和配置

  3. ​需要依赖注入​​:使用DelegatingFilterProxy方式

  4. ​性能考虑​​:在Filter中避免耗时操作,特别是高优先级Filter

  5. ​异常处理​​:在Filter中妥善处理异常,避免影响整个应用

http://www.dtcms.com/a/303164.html

相关文章:

  • 基于Python的arXiv论文数据分析系统:从爬取到可视化的完整实践
  • flexbuild-imx91 imx93
  • Java-分布式锁
  • Lakehouse: Unifying DW Advanced Analytics in Open Platforms
  • 【C语言网络编程基础】TCP并发网络编程:io多路复用
  • 开源赋能产业,生态共筑未来 | 开源科学计算与系统建模(openSCS)分论坛圆满举行
  • 笔试——Day21
  • JS面试题
  • Linux 远程连接与文件传输:从基础到高级配置
  • QT之QThread 与 QtConcurrent
  • 【自动化运维神器Ansible】Ansible常用模块之cron模块详解
  • GaussDB as的用法
  • 【GaussDB】内存资源告急:深度诊断一起“memory temporarily unavailable“故障
  • DMETL安装流程及简单使用
  • OpenLayers 入门指南【四】:项目初始化
  • Qt小组件 - 8 图片浏览器
  • MySQL高级配置与优化实战指南
  • 利用 SQL Server 实现字符替换的高效函数
  • 第二十一天(shell练习)
  • IT运维的365天--033 跨交换机部署没有单独供电口的爱快AP到另一个地方去
  • 如何选择适合高并发环境的服务器:性能与稳定性的平衡
  • 短剧小程序系统开发:连接创作者与用户的桥梁
  • Node.js + TypeScript 开发健壮的淘宝商品 API SDK
  • 2025年07月23日秋瑶传媒一面
  • 【学习路线】AI开发工程师成长指南:从机器学习基础到大模型应用
  • 调色总监的“色彩炼金术”:在PS中创建LUT,并应用于Premiere Pro视频
  • TCP/IP 网际层详解
  • RCLAMP2574N.TCT Semtech:超低钳位TVS二极管 0.5pF超低电容+±30kV超强防护
  • 【Blender小技巧】Blender使用多边形建形工具创建多边形模型,挤出面,模型创建修改编辑UV贴图
  • PostgreSQL 与 MySQL 时间类型避坑指南