拦截器与过滤器

        过滤器是对数据进行过滤,预处理过程,当我们访问网站时,有时候会发布一些敏感信息,发完以后有的会用*替代,还有就是登陆权限控制等,一个资源,没有经过授权,肯定是不能让用户随便访问的,这个时候,也可以用到过滤器。过滤器的功能还有很多,例如实现URL级别的权限控制、压缩响应信息、编码格式等等。

  过滤器和拦截器,这两者在功能方面很类似,但是在具体技术实现方面,差距还是比较大的。在分析两者的区别之前,我们先理解一下AOP的概念,AOP不是一种具体的技术,而是一种编程思想。在面向对象编程的过程中,我们很容易通过继承、多态来解决纵向扩展。 但是对于横向的功能,比如,在所有的service方法中开启事务,或者统一记录日志等功能,面向对象的是无法解决的。所以AOP——面向切面编程其实是面向对象编程思想的一个补充。而我们今天讲的过滤器和拦截器都属于面向切面编程的具体实现。而两者的主要区别包括以下几个方面:

  1、Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。

  2、Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理的方式来执行。

  3、Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。

一、记录请求耗时的过滤器

新增类实现Filter,重写doFilter方法

spring boot怎么取消过滤器 springboot过滤器作用_拦截器

 服务启动时执行init()方法,关闭时执行destory方法

 以前的web项目可以在web.xml中进行配置,使过滤器生效,但是spring boot项目并没有web.xml因此使用以下两种方法:

1、使用配置类,注入FilterRegistrationBean

spring boot怎么取消过滤器 springboot过滤器作用_AOP_02

2、使用注解 @WebFilter,在启动类加上@ServletComponentScan使之能被读取到

@WebFilter这个注解并没有指定执行顺序的属性,可以用@Order指定顺序,如果不指定,其执行顺序依赖于Filter的名称,是根据Filter类名(注意不是配置的filter的名字)的字母顺序倒序排列,并且@WebFilter指定的过滤器优先级都高于FilterRegistrationBean配置的过滤器。

 

spring boot怎么取消过滤器 springboot过滤器作用_java_03

 

spring boot怎么取消过滤器 springboot过滤器作用_拦截器_04

二、记录请求耗时的拦截器

新增类,实现HandlerInterceptor接口

这个接口包括三个方法,preHandle是请求执行前执行的,postHandler是请求结束执行的,但只有preHandle方法返回true的时候才会执行,afterCompletion是视图渲染完成后才执行,同样需要preHandle返回true,该方法通常用于清理资源等工作。

spring boot怎么取消过滤器 springboot过滤器作用_拦截器_05

 除了实现上面的接口外,我们还需对其进行配置:

注意 pathPatterns

经查询:  /* 是拦截所有的文件夹,不包含子文件夹
                /** 是拦截所有的文件夹及里面的子文件夹

比如controller类上注解是@RequestMapping("/consumerTest")就必须配置 /**

如果是@RequestMapping("/")则可以配置 /*

这个目录是看controller配置的请求路径,而不是这个类本身所在的路径

spring boot怎么取消过滤器 springboot过滤器作用_java_06

 可以看到,我们通过拦截器实现了同样的功能。不过这里还要说明一点的是,其实这个实现是有问题的,因为preHandle和postHandle是两个方法,所以我们这里不得不设置一个共享变量start来存储开始值,但是这样就会存在线程安全问题。当然,我们可以通过其他方法来解决,比如通过ThreadLocal就可以很好的解决这个问题。不过通过这一点我们其实可以看到,虽然拦截器在很多场景下优于过滤器,但是在这种场景下,过滤器比拦截器实现起来更简单。