过滤器:
过滤器是servlet
提供的API,需要实现javax.servlet.Filter
接口。过滤器可以拦截到方法的请求和响应(ServletRequest request, SetvletResponse response),并对请求响应做出的过滤操作,比如设置字符编码、鉴权操作。
过滤器方法的入参有request,response,FilterChain,其中FilterChain
是过滤器链,使用比较简单,而request,response则关联到请求流程,因此可以对请求参数做过滤和修改,同时FilterChain过滤链执行完,并且完成业务流程后,会返回到过滤器,此时也可以对请求的返回数据做处理。
spring拦截器:
拦截器是spring
提供的API,需要实现 org.springframework.web.servlet.HandlerInterceptor
接口
拦截器拦截的是URL,获取请求中的参数信息比较麻烦;
拦截器有三个方法,相对于过滤器更加细致,有被拦截逻辑执行前、后等。
Spring中拦截器有三个方法:preHandle
,postHandle
,afterCompletion
。分别表示如下
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)表示被拦截的URL对应的方法执行前的自定义处理
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView)表示此时还未将modelAndView进行渲染,被拦截的URL对应的方法执行后的自定义处理,。
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e)表示此时modelAndView已被渲染,执行拦截器的自定义处理。
AOP:
AOP操作可以对方法(spring
管理的bean
)进行横向的拦截,最大的优势在于可以获取执行方法的参数,对方法进行统一的处理,常见使用日志,事务,请求参数安全验证等。
三者使用场景类似
从过滤器–》拦截器–》切面,拦截规则越来越细致,执行顺序依次是过滤器、拦截器、切面。
一般情况下数据被过滤的时机越早对服务的性能影响越小,因此我们在编写相对比较公用的代码时,优先考虑过滤器,然后是拦截器,最后是aop。
比如权限校验,一般情况下,所有的请求都需要做登陆校验,此时就应该使用过滤器在最顶层做校验;日志记录,一般日志只会针对部分逻辑做日志记录,而且牵扯到业务逻辑完成前后的日志记录,因此使用过滤器不能细致地划分模块,此时应该考虑拦截器,然而拦截器也是依据URL做规则匹配,因此相对来说不够细致,因此我们会考虑到使用AOP实现,AOP可以针对代码的方法级别做拦截,很适合日志功能。
AOP详细介绍
过滤器(Filter) :可以拿到原始的http请求,但是拿不到你请求的控制器和请求控制器中的方法的信息。
拦截器(Interceptor):可以拿到你请求的控制器和方法,却拿不到请求方法的参数。
切片(Aspect): 可以拿到方法的参数,但是却拿不到http请求和响应的对象
三者的区别
从上面对拦截器与过滤器的描述来看,它俩是非常相似的,都能对客户端发来的请求进行处理,它们的区别如下:
- 作用域不同
- 过滤器依赖于servlet容器,只能在 servlet容器,web环境下使用
- 拦截器依赖于spring容器,可以在spring容器中调用,不管此时Spring处于什么环境
- 细粒度的不同
- 过滤器的控制比较粗,只能在请求进来时进行处理,对请求和响应进行包装
- 拦截器提供更精细的控制,可以在controller对请求处理之前或之后被调用,也可以在渲染视图呈现给用户之后调用
- 中断链执行的难易程度不同
- 拦截器可以 preHandle方法内返回 false 进行中断,过滤器就比较复杂,需要处理请求和响应对象来引发中断,需要额外的动作,比如将用户重定向到错误页面
过滤器和拦截器非常相似,但是它们有很大的区别
最简单明了的区别就是过滤器可以修改request,而拦截器不能
过滤器需要在servlet容器中实现,拦截器可以适用于javaEE,javaSE等各种环境
拦截器可以调用IOC容器中的各种依赖,而过滤器不能
过滤器只能在请求的前后使用,而拦截器可以详细到每个方法
三者的区别和联系:
①拦截器是基于java
的反射机制的,而过滤器是基于函数回调。
②拦截器不依赖与servlet
容器,过滤器依赖与servlet
容器。
③拦截器只能对action
请求起作用,而过滤器则可以对几乎所有的请求起作用。
④拦截器可以访问action
上下文、值栈里的对象,而过滤器不能访问。
⑤在action
的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
⑥拦截器可以获取IOC
容器中的各个bean
,而过滤器就不行,这点很重要,在拦截器里注入一个service
,可以调用业务逻辑。
⑦拦截器和过滤器相似,是链式的处理模式,这样有一个缺点是每次请求都会访问action
的上下文,不够灵活;
Spring AOP
的注解有@Before
、@After
、@AfterReturning
、@AfterThrowing
、@Around
,可以更灵活的配置要监听处理的Bean,即可以对指定的方法等进行拦截处理,而不是每个接口等请求都需要进入注解关联的处理。
三者功能类似,但各有优势,从过滤器–》拦截器–》切面,拦截规则越来越细致,执行顺序依次是过滤器、拦截器、切面。一般情况下数据被过滤的时机越早对服务的性能影响越小,因此我们在编写相对比较公用的代码时,优先考虑过滤器,然后是拦截器,最后是aop。比如权限校验,一般情况下,所有的请求都需要做登陆校验,此时就应该使用过滤器在最顶层做校验