过滤器和拦截器

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...
文章列表
王小扬博客
云原生
Git
Elasticsearch
Apollo
产品
Think
生活技巧
软件开发
计算机网络
CI
DB
设计
缓存
Docker
Node
操作系统
Java
大前端
Nestjs
其他
PHP
AI