千家信息网

SpringBoot中过滤器Filter怎么用

发表于:2025-12-01 作者:千家信息网编辑
千家信息网最后更新 2025年12月01日,小编给大家分享一下SpringBoot中过滤器Filter怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!I. 背景在
千家信息网最后更新 2025年12月01日SpringBoot中过滤器Filter怎么用

小编给大家分享一下SpringBoot中过滤器Filter怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

I. 背景

在正式开始之前,有必要先简单看一下什么是Filter(过滤器),以及这个有什么用

1. Filter说明

Filter,过滤器,属于Servlet规范,并不是Spring独有的。其作用从命名上也可以看出一二,拦截一个请求,做一些业务逻辑操作,然后可以决定请求是否可以继续往下分发,落到其他的Filter或者对应的Servlet

简单描述下一个http请求过来之后,一个Filter的工作流程:

  • 首先进入filter,执行相关业务逻辑

  • 若判定通行,则进入Servlet逻辑,Servlet执行完毕之后,又返回Filter,最后在返回给请求方

  • 判定失败,直接返回,不需要将请求发给Servlet

插播一句:上面这个过程,和AOP中的@Around环绕切面的作用差不多

2. 项目搭建

接下来我们搭建一个web应用方便后续的演示,借助SpringBoot搭建一个web应用属于比较简单的活;

创建一个maven项目,pom文件如下

    org.springframework.boot    spring-boot-starter-parent    2.1.7         UTF-8    UTF-8    Finchley.RELEASE    1.8            org.springframework.boot        spring-boot-starter-web                com.alibaba        fastjson        1.2.45                                            org.springframework.boot                spring-boot-maven-plugin                                    spring-milestones        Spring Milestones        https://repo.spring.io/milestone                    false            

II. Filter教程

1. 使用说明

在SpringBoot项目中,如果需要自定义一个Filter,并没有什么特殊的地方,直接实现接口即可,比如下面一个输出请求日志的拦截器

@Slf4j@WebFilterpublic class ReqFilter implements Filter {    public ReqFilter() {        System.out.println("init reqFilter");    }    @Override    public void init(FilterConfig filterConfig) throws ServletException {    }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)            throws IOException, ServletException {        HttpServletRequest req = (HttpServletRequest) request;        log.info("url={}, params={}", req.getRequestURI(), JSON.toJSONString(req.getParameterMap()));        chain.doFilter(req, response);    }    @Override    public void destroy() {    }}

实现一个自定义的Filter容易,一般有两个步骤

  • 实现 Filter 接口

  • doFilter方法中添加业务逻辑,如果允许访问继续,则执行chain.doFilter(req, response);; 不执行上面这一句,则访问到此为止

接下来的一个问题就是如何让我们自定义的Filter生效,在SpringBoot项目中,有两种常见的使用方式

  • @WebFilter

  • 包装Bean: FilterRegistrationBean

a. WebFilter

这个注解属于Servlet3+,与Spring也没有什么关系,所以问题来了,当我在Filter上添加了这个注解之后,Spring怎么让它生效呢?

  • 配置文件中显示使用注解 @ServletComponentScan

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

WebFilter常用属性如下,其中urlPatterns最为常用,表示这个filter适用于哪些url请求(默认场景下全部请求都被拦截)

属性名类型描述
filterNameString指定过滤器的 name 属性,等价于
valueString[]该属性等价于 urlPatterns 属性。但是两者不应该同时使用。
urlPatternsString[]指定一组过滤器的 URL 匹配模式。等价于 标签。
servletNamesString[]指定过滤器将应用于哪些 Servlet。取值是 @WebServlet 中的 name 属性的取值,或者是 web.xml 中 的取值。
dispatcherTypesDispatcherType指定过滤器的转发模式。具体取值包括:ASYNC、ERROR、FORWARD、INCLUDE、REQUEST。
initParamsWebInitParam[]指定一组过滤器初始化参数,等价于 标签。
asyncSupportedboolean声明过滤器是否支持异步操作模式,等价于 标签。
descriptionString该过滤器的描述信息,等价于 标签。
displayNameString该过滤器的显示名,通常配合工具使用,等价于 标签。
b. FilterRegistrationBean

上面一种方式比较简单,后面会说到有个小问题,指定Filter的优先级比较麻烦,

下面是使用包装bean注册方式

@Beanpublic FilterRegistrationBean orderFilter() {    FilterRegistrationBean filter = new FilterRegistrationBean<>();    filter.setName("reqFilter");    filter.setFilter(new ReqFilter());    // 指定优先级    filter.setOrder(-1);    return filter;}

2. 常见问题

上面整完,就可以开始测试使用过滤器了,在进入实测环节之前,先来看两个常见的问题

  • Filter作为Servelt的组件,怎么与SpringBoot中的Bean交互

  • 多个Filter之间的优先级怎么确定

a. Filter依赖Bean注入问题

如果有小伙伴使用SpringMVC + web.xml方式来定义Filter,就会发现自定义的Filter中无法通过@Autowired方式来注入Spring的bean

我之前使用的是spring4 Servlet2+ ,存在上面的问题,如果有不同观点请留言告诉我,感谢

SpringBoot中可以直接注入依赖的Bean,从上面的第二种注册方式可以看到,Spring将Filter封装成了一个Bean对象,因此可以直接注入依赖的Bean

下面定义一个AuthFilter,依赖了自定义的DemoBean

@Data@Componentpublic class DemoBean {    private long time;    public DemoBean() {        time = System.currentTimeMillis();    }    public void show() {        System.out.println("demo bean!!! " + time);    }}@Slf4j@WebFilterpublic class AuthFilter implements Filter {    @Autowired    private DemoBean demoBean;    public AuthFilter() {        System.out.println("init autFilter");    }    @Override    public void init(FilterConfig filterConfig) throws ServletException {    }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)            throws IOException, ServletException {        log.info("in auth filter! {}", demoBean);        // 测试,用header中的 tx-demo 来判断是否为认证的请求        HttpServletRequest req = (HttpServletRequest) request;        String auth = req.getHeader("tx-demo");        if ("yihuihui".equals(auth)) {            // 只有认证的请求才允许访问,请求头中没有这个时,不执行下面的的方法,则表示请求被过滤了            // 在测试优先级时打开下面的注释            // chain.doFilter(request, response);        } else {            chain.doFilter(request, response);        }    }    @Override    public void destroy() {    }}
b. 优先级指定

Filter的优先级指定,通过我的实际测试,@Order注解没有用,继承 Ordered接口也没有用,再不考虑web.xml的场景下,只能通过在注册Bean的时候指定优先级

实例如下,三个Filter,两个通过@WebFilter注解方式注册,一个通过FilterRegistrationBean方式注册

@Slf4j@Order(2)@WebFilterpublic class AuthFilter implements Filter, Ordered {  ...}@Slf4j@Order(1)@WebFilterpublic class ReqFilter implements Filter, Ordered {  ...}@Slf4jpublic class OrderFilter implements Filter {}@ServletComponentScan@SpringBootApplicationpublic class Application {    @Bean    public FilterRegistrationBean orderFilter() {        FilterRegistrationBean filter = new FilterRegistrationBean<>();        filter.setName("orderFilter");        filter.setFilter(new OrderFilter());        filter.setOrder(-1);        return filter;    }    public static void main(String[] args) {        SpringApplication.run(Application.class);    }}

3. 测试

上面定义了三个Filter,我们主要验证下优先级,如果@Order注解生效,那么执行的先后顺序应该是

OrderFilter -> ReqFilter -> AuthFilter

如果不是上面的顺序,那么说明@Order注解没有用

@RestControllerpublic class IndexRest {    @GetMapping(path = {"/", "index"})    public String hello(String name) {        return "hello " + name;    }}

(上文截图源码来自: org.apache.catalina.core.ApplicationFilterFactory#createFilterChain

上面是测试时关键链路的断点截图,从数组中可以看出 AuthFilter的优先级大于ReqFilter, 下面实际的输出也说明了@Order注解不能指定Filter的优先级(不知道为什么网络上有大量使用Order来指定Filer优先级的文章!!!)

接下来我们的问题就是WebFilter注解来注册的Filter的优先级是怎样的呢,我们依然通过debug来看,关键代码路径为: org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#selfInitialize

  • OrderFiler是我们手动注册并设置优先级为-1

  • ReqFilter, AuthFilter通过 WebFillter方式注册,默认优先级为2147483647,相同优先级的情况下,根据名字先后顺序来决定

III. 小结

本文主要介绍了过滤器Filter的使用方式,以及常见的两个问题解答,文中内容穿插了一点源码的分析截图,并未深入,如有兴趣的同学可以根据文中提的几个关键位置探索一番

下面简单小结下文中内容

1. Filter使用

自定义Filter的实现

  • 实现Filter接口

  • doFilter方法中,显示调用chain.doFilter(request, response);表示请求继续;否则表示请求被过滤

注册生效

  • @ServletComponentScan自动扫描带有@WebFilter注解的Filter

  • 创建Bean: FilterRegistrationBean 来包装自定义的Filter

2. IoC/DI

在SpringBoot中Filter可以和一般的Bean一样使用,直接通过Autowired注入其依赖的Spring Bean对象

3. 优先级

通过创建FilterRegistrationBean的时候指定优先级,如下

@Beanpublic FilterRegistrationBean orderFilter() {    FilterRegistrationBean filter = new FilterRegistrationBean<>();    filter.setName("orderFilter");    filter.setFilter(new OrderFilter());    filter.setOrder(-1);    return filter;}

此外格外注意, @WebFilter声明的Filter,优先级为2147483647(最低优先级)

  • @Order注解不能指定Filter优先级

  • @Order注解不能指定Filter优先级

  • @Order注解不能指定Filter优先级

以上是"SpringBoot中过滤器Filter怎么用"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

优先级 过滤器 注解 方式 问题 等价 属性 面的 测试 标签 两个 内容 常见 接口 逻辑 项目 接下来 业务 关键 截图 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 成都有哪些是软件开发学校 中太服务器怎么样 mysql数据库注释是什么意思 网络安全法与公民自由 数据库在客户关系管理的主要功能 工业软件开发方式 手机泰拉瑞亚在线联机服务器 云服务器防护设备 无人机网络安全军工股 投标数据库 删数据库的程序员怎么样了 数据库出现什么类型的不一致 网络安全手抄报简单又好画四年级 网络安全短动画一分钟 nba服务器不闪退 政府采购软件开发企业排名 停车场收费软件数据库查询密码 迪科数金的软件开发怎么样 软件开发一定要学高数吗 吉隆2020年外贸数据库怎么找 保护无线网络安全的措施 慧享网络技术有限公司怎么样 中国科学引文数据库和科技核心 制作本地数据库 高压直流 服务器 计算机网络技术第四版书 数据库中的关键字分大小写吗 选择运算 数据库 开展 网络安全法 宣传 牟平区商城软件开发推荐
0