欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Boot添加Filter过滤器

程序员文章站 2022-04-15 17:46:51
添加过滤器方便规范管理,我们直接在项目下新建filter文件夹,并创建类。此处名字就随意一点了。创建自定义Filter实现javax.servlet.Filter接口重写doFilter方法。添加@Component注解@Slf4j@Componentpublic class TestFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws Servle...

添加过滤器

方便规范管理,我们直接在项目下新建filter文件夹,并创建类。此处名字就随意一点了。
Spring Boot添加Filter过滤器
创建自定义Filter

  • 实现javax.servlet.Filter接口
  • 重写doFilter方法。
  • 添加@Component注解
@Slf4j
@Component
public class TestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        log.info("testFilter is running ");

        // TODO 过滤处理

        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

创建过滤器配置类

  • 添加@Configuration注解
  • 引入自定义过滤器对象(在过滤器已添加@Component注解)
  • 自定义方法,添加@Bean注解 ,并返回FilterRegistrationBean
@Configuration
public class FilterConfig {

    @Autowired
    private TestFilter testFilter;

    @Bean
    public FilterRegistrationBean registerFilter(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();

        filterRegistrationBean.setFilter(testFilter); //设置过滤器
        filterRegistrationBean.addUrlPatterns("/*"); //设置过滤的URL
        filterRegistrationBean.setName("testFilter"); //设置过滤器名称
        filterRegistrationBean.setOrder(2); //设置过滤器顺序(存在多个过滤器,值越小,越先执行)

        return filterRegistrationBean;
    }
}

这样我们就可以直接写个DemoController进行测试了。
Spring Boot添加Filter过滤器
我在自定义过滤器的doFilter方法中暂时没有做任何操作,仅仅只是输出了日志,这里从日志中已经看到TestFilter过滤器已经执行。

另一种添加过滤器的方式

本着一题多解的心态,去搜了一下还有没有别的配置过滤器的方法。答案是有的,那就直接上码。

创建自定义过滤器

  • 实现javax.servlet.Filter接口
  • 重写doFilter方法。
  • 添加@WebFilter注解,并指定过滤器名称,url。这里的过滤器类名有讲究,稍后讲。
@Slf4j
@WebFilter(filterName = "firstFilter",urlPatterns = {"/*"})
// @Order(0) 此处的Order 是指定类的加载顺序,而不是执行顺序
public class FirstFilter implements Filter {

    public FirstFilter(){
        log.info("FirstFilter is creating");
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        filterChain.doFilter(servletRequest,servletResponse);
        log.info("firstFilter is running ");
    }

    @Override
    public void destroy() {

    }
}

在启动类中添加@ServletComponentScan注解

@ServletComponentScan //@ServletComponentScan扫描带@WebFilter、@WebServlet、@WebListener
@SpringBootApplication
public class SpringbootDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootDemoApplication.class, args);
    }

}

创建多个过滤器就按照上述模板来就好。

那么问题来了,使用@WebFilter创建多个过滤器如何指定过滤器的执行顺序嘞?第一种方法是可以设置的。

在看博客的时候,看到在自定义过滤器上面添加了@Order注解,但是在测试的过程中发现,并不是按照order的顺序在执行。

下面展示测试案例

Spring Boot添加Filter过滤器
Spring Boot添加Filter过滤器
Spring Boot添加Filter过滤器
运行日志:
Spring Boot添加Filter过滤器
通过日志可以看到,使用@WebFilter创建的三个自定义过滤器的执行并没有按照所想的顺序执行。

然后去搜了一下有关@Order注解,注解@Order的作用是定义Spring容器加载Bean的顺序。呐,只是加载顺序,不是执行顺序。
通过在自定义过滤器的无参构造方法中添加了一行日志,在打印过程中,确实如此。
Spring Boot添加Filter过滤器

带着问题去搜了一下,过滤器的执行顺序是与自己定义过滤器名称的hash值有关。

验证1:
创建HashMap,将自定义过滤器的名称作为key并遍历输出。
Spring Boot添加Filter过滤器
输出顺序结果与自定义三个过滤器的运行顺序结果一致。
Spring Boot添加Filter过滤器

验证2:
将按照hash顺序的字符串作为自定义过滤器的名称。
Spring Boot添加Filter过滤器

我们将FirstFilter,SecondFilter,ThirdFilter 类名分别改为 UrlFilter,RoleFilter,LogFilter。这样一来再执行测试。
Spring Boot添加Filter过滤器
这里结果是不成立的。并没有按照顺序执行。

又去搜了一些文章,并没有找到正确的原因。

在暂时还没有找到正确的办法前,如果过滤同一url的多个过滤器,要指定顺序,建议使用第一种方法。如果后续第二种找到了正确的解决方法再来更新此博客。

本文地址:https://blog.csdn.net/u012708900/article/details/109582150

相关标签: Spring Boot