总结 拦截器(Interceptor) 和 过滤器(Filter)的区别

本文总结了拦截器(Interceptor)和过滤器(Filter)的区别。介绍了Filter的概念、作用、API、链与生命周期,它基于函数回调,在请求进入容器后、Servlet前处理。还介绍了Interceptor,它基于反射机制,是Spring组件。最后从实现原理、使用范围等多方面对比了二者区别。

一、前言

拦截器(Interceptor) 和 过滤器(Filter)的区别是面试中常问的问题,也是开发中容易被大家混淆的问题,在此总结下,希望对大家有所帮助。

二、Filter 介绍

2.1、概念

Servlet规范中三个技术 Servlet、Listener、Filter(顺序为L F S)。

Filter是sun公司中servlet2.3后增加的一个新功能,在javaEE中定义了一个接口 javax.servlet.Filter来描述过滤器。

2.2、作用

通过Filter可以拦截访问web资源的请求与响应操作.。

WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

2.3、举例子

在java web中,针对传入的request,或response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符。

2.4、Filter API介绍

Filter是javax.servlet包下的一个接口主要有以下三个方法:

destory()

doFilter(ServletRequest request,ServletResponse response,FilterCjain chain)

init(FilterConfig filterConfig)

2.5、Filter链与Filter生命周期

1)Filter链介绍

多个Filter对同一个资源进行了拦截,那么当我们在开始的Filter中执行chain.doFilter(request,response)时,是访问下一下Filter,直到最后一个Filter执行时,它后面没有了Filter,才会访问web资源。

2)多个FIlter的访问顺序问题

它们的执行顺序取决于在web.xml文件中配置的先后顺序。

3)Filter生命周期

当服务器启动,会创建Filter对象,并调用init方法,只调用一次。

当访问资源,路径与Filter的拦截路径匹配,会执行Filter中的doFilter方法,
这个方法是真正拦截操作的方法。

当服务器关闭时,会调用Filter的destroy方法来进行销毁操作。

过滤器是JavaEE标准,采用函数回调的方式进行。是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理。

三、 Interceptor 介绍

拦截器是spring容器的,是spring支持的。

java里的拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重用部分的方式。

在面向切面编程AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前,进行拦截,然后在之前或之后加入某些操作。

四、 总结 Filter 和 Interceptor 区别

1、实现原理不同

拦截器是基于java的反射机制的,而过滤器是基于函数回调。

2、使用范围不同

过滤器 实现的是 javax.servlet.Filter 接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。

拦截器(Interceptor) 它是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。不仅能应用在web程序中,也可以用于Application、Swing等程序中。

3、触发时机不同

过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。

拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。

在这里插入图片描述

4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

6、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。拦截器可以获取ioc中的service bean实现业务逻辑。

在Spring中,过滤器Filter)、拦截器InterceptorAOP(面向切面编程)既有区别又有联系。 ### 区别 - **实现机制**:拦截器基于Java的反射机制,使用代理模式;而过滤器基于函数回调。拦截器不依赖servlet容器,过滤器依赖于servlet容器[^2]。 - **作用范围**:拦截器只能对action起作用,而过滤器可以对几乎所有的请求起作用,能够保护资源[^2]。 - **访问权限**:拦截器可以访问action上下文堆栈里面的对象,过滤器则不能[^2]。 - **执行顺序**:执行顺序为过滤前 - 拦截前 - Action处理 - 拦截后 - 过滤后[^2]。 ### 联系 它们都可以对程序的流程进行拦截处理,起到增强功能控制访问的作用。例如在Spring Boot中,都可以对请求进行一定的前置或后置处理。而且它们都可以用于实现一些通用的功能,如日志记录、权限验证等。 ### 代码示例 以下是简单的过滤器拦截器AOP的代码示例: #### 过滤器示例 ```java import javax.servlet.*; import java.io.IOException; public class MyFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 过滤前处理 System.out.println("Filter: Before processing"); chain.doFilter(request, response); // 过滤后处理 System.out.println("Filter: After processing"); } } ``` #### 拦截器示例 ```java import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 拦截前处理 System.out.println("Interceptor: Before handler execution"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 拦截后处理 System.out.println("Interceptor: After handler execution"); } } ``` #### AOP示例 ```java import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect @Component public class MyAspect { @Pointcut("execution(* com.example.service.*.*(..))") public void serviceMethods() {} @Before("serviceMethods()") public void beforeServiceMethod(JoinPoint joinPoint) { // 增强处理(前置通知) System.out.println("AOP: Before service method execution"); } @After("serviceMethods()") public void afterServiceMethod(JoinPoint joinPoint) { // 增强处理(后置通知) System.out.println("AOP: After service method execution"); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值