springboot使用之多个filter的执行顺序以及配置方式

 更新时间:2021年08月12日 16:28:49   作者:east123321  
这篇文章主要介绍了springboot使用之多个filter的执行顺序以及配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

springboot 多个filter的执行顺序以及配置

当项目中有多个filter时,为了便于管理,可以创建一个配置文件,对所有的filter进行管理。

有的方法可能同时需要多个filter依次对其进行过滤,这时候便需要对filter的执行进行优先级的排序。如下:

新建一个配置文件ComponentFilterOrderConfig.java

先生成一个过滤器的bean,再把过滤器的bean注入到FilterRegistrationBean中,并设置一些属性,过滤的url,执行的顺序之类的(order的数值越小,优先级越高)即可。

在MyHiddenHttpMethodFilter.java和TokenAuthorFilter.java里面不需要在添加注解@WebFilter(urlPatterns={})或@Configuration @Component等注解

@Configuration
public class ComponentFilterOrderConfig {
 @Bean
 public Filter MyHiddenHttpMethodFilter(){
  return new MyHiddenHttpMethodFilter();//自定义的过滤器
 }
 @Bean
 public Filter tokenAuthorFilter(){
  return new TokenAuthorFilter();//自定义的过滤器
 }
 @Bean
 public FilterRegistrationBean filterRegistrationBean1(){
  FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean();
  filterRegistrationBean.setFilter(MyHiddenHttpMethodFilter());
  filterRegistrationBean.addUrlPatterns("/app/approval/*");
  filterRegistrationBean.setOrder(6);//order的数值越小 则优先级越高
  return filterRegistrationBean;
 }
 @Bean
 public FilterRegistrationBean filterRegistrationBean2(){
  FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean();
  filterRegistrationBean.setFilter(tokenAuthorFilter());
  filterRegistrationBean.addUrlPatterns("/app/*");
  filterRegistrationBean.setOrder(7);
  return filterRegistrationBean;
 }  
}

SpringBoot 使用 Filter 的正确姿势

Filter 是 JavaEE 中 Servlet 规范的一个组件,位于包javax.servlet 中,它可以在 HTTP 请求到达 Servlet 之前,被一个或多个Filter处理。

它的工作流程如图:

Filter的这个特性在生产环境中有很广泛的应用,如:修改请求和响应、防止xss攻击、包装二进制流使其可以多次读,等等。

实际工作中,我们都是使用 SpringBoot 进行业务开发,本文总结三种 Filter 用法,SpringBoot 版本采用目前最新的 v2.3.1.RELEASE

1. 编写Filter

要编写 Filter ,只需要实现javax.servlet.Filter接口就可以了

public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("MyFilter");
        // 要继续处理请求,必须添加 filterChain.doFilter()
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

Filter 接口有三个方法:init(),doFilter(),destroy()。

其中doFilter()需要自己实现,其余两个是default的,可以不用实现。

注意:如果Filter要使请求继续被处理,就一定要调用filterChain.doFilter()!

2. 配置Filter被 Spring 管理

让自定义的 Filter 被 Spring 的 IOC 容器管理,有三种实现方式,各有优缺点。下面课代表给大家总结一下:

1. 使用@Component+@Order

在刚刚定义的MyFilter类上加上@Component和@Order注解,即可被Spring管理

@Component
@Order(1)
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("MyFilter");
        // 要继续处理请求,必须添加 filterChain.doFilter()
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

没错就这么简单,这样 MyFilter 就生效了,写个Controller 调用一下就可以看到效果。

当有多个Filter时,这里的@Order(1)注解会指定执行顺序,数字越小,越优先执行,如果只写@Order,默认顺序值是Integer.MAX_VALUE。

@Component + @Order 注解方式配置简单,支持自定义 Filter 顺序。缺点是只能拦截所有URL,不能通过配置去拦截指定的 URL。

2.@WebFilter+@ServletComponentScan

在 MyFilter上添加@WebFilter注解,并在启动类上增加@ServletComponentScan("com.zhengxl.filterdemo.filter")注解,参数就是Filter所在的包路径,相当于告诉 SpringBoot,去哪里扫描 Filter

@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("MyFilter");
        // 要继续处理请求,必须添加 filterChain.doFilter()
        filterChain.doFilter(servletRequest,servletResponse);
    }
}
@SpringBootApplication
@ServletComponentScan("com.zhengxl.filterdemo.filter")
public class FilterDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(FilterDemoApplication.class, args);
    }
}

@WebFilter+@ServletComponentScan 注解方式支持对 Filter 匹配指定URL,但是不支持指定 Filter 的执行顺序。

3. JavaConfig 配置方式

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean registerMyFilter(){
        FilterRegistrationBean<MyFilter> bean = new FilterRegistrationBean<>();
        bean.setOrder(1);
        bean.setFilter(new MyFilter());
        // 匹配"/hello/"下面的所有url
        bean.addUrlPatterns("/hello/*");
        return bean;
    }
    @Bean
    public FilterRegistrationBean registerMyAnotherFilter(){
        FilterRegistrationBean<MyAnotherFilter> bean = new FilterRegistrationBean<>();
        bean.setOrder(2);
        bean.setFilter(new MyAnotherFilter());
        // 匹配所有url
        bean.addUrlPatterns("/*");
        return bean;
    }
}

通过 Java 代码显式配置 Filter ,功能强大,配置灵活。只需要把每个自定义的 Filter 声明成 Bean 交给 Spring 管理即可,还可以设置匹配的 URL 、指定 Filter 的先后顺序。

3. 三种方式对比

以上介绍完 SpringBoot 中三种 Filter的使用姿势,非常简单,下面列个表格总结一下:

使用方式 排序 指定URL
@Component @Order 1 0
@WebFilter @ServletComponentScan 0 1
JavaConfig 1 1

实际使用过程中,可以按照业务需求选择合适的使用方式,比如:如果编写的过滤器要拦截所有请求,不需要指定URL,那选择最简单的 @Component+@Order 就非常合适。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java中单例模式讲解

    java中单例模式讲解

    这篇文章主要介绍了java中单例模式,本文通过简单的案例,讲解了该模式在java中的使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • Java图像处理之RGB调色面板

    Java图像处理之RGB调色面板

    这篇文章主要为大家详细介绍了Java图像处理之RGB调色面板,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • Fluent Mybatis学习之Update语法实践

    Fluent Mybatis学习之Update语法实践

    Fluent MyBatis是一个MyBatis的增强工具,没有对mybatis做任何修改。本篇文章将详细介绍对Fluent Mybatis中的update语法进行验证。代码具有一定价值,感兴趣的小伙伴可以学习一下
    2021-11-11
  • 详解springboot配置多个redis连接

    详解springboot配置多个redis连接

    Spring Boot为Redis, MongoDB, Elasticsearch, Solr和Gemfire提供自动配置。本文详细介绍了springboot配置多个redis连接,有兴趣的可以了解一下。
    2017-04-04
  • redis在java中的使用(实例讲解)

    redis在java中的使用(实例讲解)

    下面小编就为大家带来一篇redis 在java中的使用(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • 一文告诉你为什么要重写hashCode()方法和equals()方法

    一文告诉你为什么要重写hashCode()方法和equals()方法

    本篇文章带大家了解一下为什么重写hashCode()方法和equals()方法,文中有非常详细的说明以及代码示例,对正在学习java的小伙伴们很有帮助,需要的朋友可以参考下
    2021-05-05
  • 使用maven方式创建springboot项目的方式

    使用maven方式创建springboot项目的方式

    使用Spring Initializr创建spring boot项目,因为外网问题导致很难成功,所以只能使用maven方式,这里介绍下使用maven方式创建springboot项目的方法,感兴趣的朋友一起看看吧
    2022-09-09
  • @PropertySource 无法读取配置文件的属性值解决方案

    @PropertySource 无法读取配置文件的属性值解决方案

    这篇文章主要介绍了@PropertySource 无法读取配置文件的属性值解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 解决shiro 定时监听器不生效的问题 onExpiration不调用问题

    解决shiro 定时监听器不生效的问题 onExpiration不调用问题

    这篇文章主要介绍了解决shiro 定时监听器不生效的问题 onExpiration不调用问题。具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 浅谈Java中的Filter过滤器

    浅谈Java中的Filter过滤器

    本篇文章主要介绍了浅谈Java中的Filter过滤器,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02

最新评论