你摸鱼,我摸鱼,老板路虎变青桔~
走过路过不要错过,在摸鱼的小伙伴来看一看啦~

1.概述
过滤器(Filter)和拦截器(Interceptor)是在Java Web应用中用于处理请求和响应的两种重要组件,它们可以用于实现一些通用的逻辑、对请求进行预处理或后处理等操作。
2.基本概念:
过滤器(Filter):
- 过滤器是Servlet规范中的一种对象,用于在请求到达Servlet之前或响应离开Servlet之前对请求和响应进行预处理和后处理。
- 过滤器的主要作用是对Web应用的请求进行过滤和处理,可以用于检查请求参数、修改请求或响应头部、记录日志等操作。
- 过滤器的生命周期由容器管理,可以在web.xml文件中配置过滤器,指定过滤器的URL映射和执行顺序。
- 过滤器是基于回调函数的,可以在请求到达时执行
doFilter()方法,在响应离开时执行。
拦截器(Interceptor):
- 拦截器是Spring框架提供的一种机制,用于拦截请求和响应的处理流程,可以在方法调用前后、异常处理等时机执行一些逻辑。
- 拦截器通常用于在请求处理之前或之后执行额外的逻辑,如日志记录、权限验证、性能监控等。
- 拦截器是Spring框架提供的,不依赖于Servlet规范,可以很方便地与Spring框架集成。
- 拦截器是基于AOP(面向切面编程)的概念,可以通过实现
HandlerInterceptor接口或继承HandlerInterceptorAdapter类来创建拦截器。
3.区别:
- 生命周期:过滤器是Servlet规范定义的,由Servlet容器管理,而拦截器是Spring框架提供的,由Spring容器管理。
- 作用范围:过滤器属于Servlet规范,作用于Web应用的整个生命周期,而拦截器作用于Spring MVC框架中的Controller层,更细粒度地控制请求处理流程。
- 实现方式:过滤器是基于回调函数实现的,拦截器则是基于反射机制,更加灵活且与Spring框架集成更紧密。
非常官方哈,那我xue微微的总结一下哈

过滤器和拦截器都是用于对请求和响应进行预处理和后处理的机制,不同的是过滤器是Servlet规范中的对象,作用于Servlet之前或之后,由容器管理,配置在web.xml中,同时过滤器主要对请求进行过滤和处理,如检查参数、修改头部信息等。拦截器是Spring框架提供的,不依赖于Servlet规范,用于方法调用前后、异常处理时执行逻辑。拦截器常用于权限验证、日志记录等,基于AOP,通过实现接口或继承类来创建。简而言之,拦截器由Spring框架管理,过滤器则由Servlet容器进行管理。
4.执行顺序:
过滤器的执行顺序总是优于拦截器的:
用户发起http请求--》过滤器--》拦截器--》分发请求到controller--》service类--》持久层
5.使用方法:
拦截器的使用:
1.拦截器中有三个方法,分别是preHandle(),postHandle(),afterCompletion();
preHandle():在请求到达 Controller 之前,preHandle 方法可以用来进行拦截器的前置处理。它可以用来做一些预处理操作,比如日志记录、权限校验、修改请求等。如果 preHandle 返回 false,则表示拦截器不继续执行,请求将被拦截并不会到达 Controller。
postHandle():Controller处理之后,在视图渲染之前调用,所以在这里可以对ModelAndView对象进行操作。
afterCompletion():在整个请求结束之后调用,就是渲染了视图之后调用,主要是一些善后工作,用于资源清理。比如释放资源、记录日志、统计请求时间等。

比如若依框架提供的防止重复提交拦截器:

如果想使用进行拦截器的话只需要实现HandlerInterceptor,重写preHandle()方法即可。拦截器是通过拦截器链(Interceptor Chain)的方式工作的,每个拦截器的preHandle方法返回true时,才会继续调用下一个拦截器的preHandle方法;如果其中一个拦截器的preHandle方法返回false,那么整个拦截器链的执行就会中断。在Spring框架中,拦截器是通过配置拦截器链的顺序来确定有多少个preHandle方法被调用的。通常在配置类中通过addInterceptors()方法将拦截器添加到拦截器链中,并且可以通过order()方法指定拦截器的执行顺序。例如:

拦截器优点:
-
细粒度控制: 拦截器可以针对特定的请求、响应、处理器等进行拦截,提供更细粒度的控制,允许对请求处理过程中的不同阶段进行干预和处理。
-
模块化设计: 拦截器的设计符合模块化原则,可以将不同功能的处理逻辑分离到不同的拦截器中,提高代码的可维护性和可复用性。
-
方便扩展: 可以通过配置多个拦截器,实现不同功能的拦截逻辑,方便进行功能扩展和定制化处理。
-
易于集成: 拦截器与Spring框架集成紧密,可以方便地与其他Spring组件和特性结合使用,如AOP、事务管理等。
拦截器缺点:
-
性能开销: 拦截器会在请求处理过程中加入额外的拦截逻辑,可能会对性能产生一定的开销,特别是当拦截器逻辑复杂或者拦截器链较长时。
-
不直接操作请求和响应: 相比于过滤器,拦截器无法直接操作请求和响应对象,只能通过HandlerMethod参数来获取请求和响应信息,有时会限制一些功能的实现。
-
仅适用于Spring MVC: 拦截器是Spring MVC框架的一部分,只能应用于基于Spring MVC的Web应用程序,无法在其他环境中使用。
-
执行顺序难以控制: 拦截器的执行顺序由配置的顺序决定,有时可能会出现拦截器执行顺序不符合预期的情况,需要额外的配置来处理。
过滤器的使用:
过滤器中也有三个方法,分别是init(),doFilter(),destroy();
init():方法在过滤器实例化后立即被调用,用于初始化过滤器,在 init() 方法中,通常可以进行一些初始化操作,如获取配置信息、建立数据库连接等,并且只会在过滤器初始化时调用一次。
doFilter():doFilter() 方法是过滤器的核心方法,用于对请求进行预处理,调用 FilterChain 对象中的 doFilter() 方法来将请求传递给下一个过滤器或目标资源,如果被引用就会一直执行,也是一个链式调用。
destroy():destroy() 方法在过滤器被销毁前被调用,用于清理过滤器的资源。在 destroy() 方法中,通常可以进行一些资源释放操作,如关闭数据库连接等。destroy() 方法只会在过滤器销毁时调用一次。

1.自定义一个过滤器类:

2.在配置类中注册过滤器:

还有不用自己配置的,直接继承OncePerRequestFilter就可以实现自定义的过滤器,因为OncePerRequestFilter是Spring提供的实现了javax.servlet.Filter接口的过滤器基类,它确保doFilterInternal方法会被调用
比如这个对接口URL的过滤:

过滤器优点:
对请求进行统一的预处理和后处理,实现通用的功能,如日志记录、权限控制等
过滤器缺点:
过滤器(Filter)在Servlet规范中的缺点是:
每个过滤器实例只会在容器初始化时调用一次。这意味着当Web应用程序启动时,容器会实例化过滤器并调用其init()方法进行初始化,之后过滤器实例会一直存在于内存中,直到容器关闭才会销毁。
-
无法动态更新过滤器配置:一旦过滤器被初始化,就无法动态更改其配置。如果需要修改过滤器的配置,必须重新部署应用程序或重启容器才能生效。
-
性能开销:过滤器实例在容器初始化时被创建并常驻内存,可能会占用一定的系统资源。对于一些需要频繁变更配置或根据请求动态调整行为的场景,这种设计可能会带来性能开销。
-
限制灵活性:过滤器的生命周期是由容器管理的,开发者无法自由控制过滤器实例的创建和销毁时机,限制了灵活性和定制能力。
总结:
总的来说,如果是Spring项目,优先使用拦截器,因为拦截器与Spring项目的关系更加贴切,同时在Spring项目中,过滤器能做到的拦截器都能做到,它能深入方法,异常抛出前后,灵活性更强,更加解耦。过滤器的话一般用于URL级别的权限控制就可以了。

本文目的是编写的同时也帮助自己梳理和加深记忆,如有不足之处欢迎各位同学指导纠正~
2423

被折叠的 条评论
为什么被折叠?



