过滤器和拦截器

notion image

总结

  1. 实现原理不同
      • 过滤器基于函数回调机制实现。
      • 拦截器基于Java反射机制(动态代理)实现。
  1. 使用范围不同
      • 过滤器依赖于Servlet容器,只能在Web程序中使用。
      • 拦截器是Spring组件,可以在多种应用环境中使用,不仅限于Web程序。
  1. 触发时机不同
      • 过滤器在请求进入Servlet之前进行预处理,请求结束在servlet处理之后。
      • 拦截器在请求进入Controller之前进行预处理,请求结束在Controller渲染视图之后。
  1. 拦截的请求范围不同
      • 过滤器可以对所有进入容器的请求起作用。
      • 拦截器只对Controller中的请求或访问static目录下的资源请求起作用。
  1. 注入Bean情况不同
      • 过滤器可以直接注入Spring的Bean。
      • 拦截器由于加载顺序问题,可能无法直接注入Bean,需要手动进行注入。
  1. 控制执行顺序不同
      • 过滤器使用@Order注解控制执行顺序。
      • 拦截器的执行顺序是注册顺序,也可以通过Order手动设置。

对比

过滤器,拦截器拦截的是URL。AOP拦截的是类的元数据(包、类、方法名、参数等)。
过滤器并没有定义业务用于执行逻辑前、后等,仅仅是请求到达就执行。 拦截器有三个方法,相对于过滤器更加细致,有被拦截逻辑执行前、后等。 AOP针对具体的代码,能够实现更加复杂的业务逻辑。
三者功能类似,但各有优势,从过滤器--拦截器--》切面,拦截规则越来越细致。 执行顺序依次是过滤器、拦截器、切面。

场景

 
拦截器可以用于实现各种功能,如身份验证、请求参数校验、权限控制等。 使用场景方面,
过滤器适用于对Web应用程序中所有请求和响应进行处理的情况,如字符编码转换、日志记录、安全控制等。
拦截器适用于对特定请求或响应进行处理的情况,如身份验证、请求参数校验、权限控制等。

过滤器 (Filter)

过滤器的配置比较简单,直接实现Filter 接口即可,也可以通过@WebFilter注解实现对特定URL拦截,看到Filter 接口中定义了三个方法。
  • init() :该方法在容器启动初始化过滤器时被调用,它在 Filter 的整个生命周期只会被调用一次。注意:这个方法必须执行成功,否则过滤器会不起作用。
  • doFilter() :容器中的每一次请求都会调用该方法, FilterChain 用来调用下一个过滤器 Filter
  • destroy(): 当容器销毁 过滤器实例时调用该方法,一般在方法中销毁或关闭资源,在过滤器 Filter 的整个生命周期也只会被调用一次

拦截器 (Interceptor)

拦截器它是链式调用,一个应用中可以同时存在多个拦截器Interceptor, 一个请求也可以触发多个拦截器 ,而每个拦截器的调用会依据它的声明顺序依次执行。
首先编写一个简单的拦截器处理类,请求的拦截是通过HandlerInterceptor 来实现,看到HandlerInterceptor 接口中也定义了三个方法。
  • preHandle() :这个方法将在请求处理之前进行调用。注意:如果该方法的返回值为false ,将视为当前请求结束,不仅自身的拦截器会失效,还会导致其他的拦截器也不再执行。
  • postHandle():只有在 preHandle() 方法返回值为true 时才会执行。会在Controller 中的方法调用之后,DispatcherServlet 返回渲染视图之前被调用。 有意思的是postHandle() 方法被调用的顺序跟 preHandle() 是相反的,先声明的拦截器 preHandle() 方法先执行,而postHandle()方法反而会后执行。
  • afterCompletion():只有在 preHandle() 方法返回值为true 时才会执行。在整个请求结束之后, DispatcherServlet 渲染了对应的视图之后执行。
Loading...
目录
文章列表
王小扬博客
产品
Think
Git
软件开发
计算机网络
CI
DB
设计
缓存
Docker
Node
操作系统
Java
大前端
Nestjs
其他
PHP