基本概念
过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。就是对请求起到过滤的作用:在监听器之后servlet之前对请求进行过滤。常见应用常见:如用户是否已经登陆、有没有权限访问该页面等等工作。
servlet:就是对request和response进行处理的容器,它在filter之后执行,servlet其中的一部分就是controller层(标记为servlet_2),还包括渲染视图层(标记为servlet_3)和进入controller之前系统的一些处理部分(servlet_1),另外我们把servlet开始的时刻标记为servlet_0,servlet结束的时刻标记为servlet_4。
拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这就是拦截器做的事情。常见应用常见是面向切面编程,即Spring AOP。它作用在servlet的内部,具体来说有三个地方:
1)servlet_1和servlet_2之间,即请求还没有到controller层;
2)servlet_2和servlet_3之间,即请求走出controller层次,还没有到渲染时图层;
3)servlet_3和servlet_4之间,即结束视图渲染,但是还没有到servlet的结束。
监听器(Listener):当一个事件发生的时候,你希望获得这个事件发生的详细信息,而并不想干预这个事件本身的进程,这就要用到监听器。就是对项目起到监听的作用,它能感知到包括request(请求域),session(会话域)和applicaiton(应用程序)的初始化和属性的变化。
从其应用场景来看,如果把Listener翻译为窃听,似乎更切合实际。
它们之间的关系,可以用一张图来表示:
在网上查询的过滤器和拦截器的区别,基本都是以下一模一样的5行话。
1、拦截器是基于Java的反射机制的,而过滤器是基于函数回调
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能
5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
执行顺序:过滤前 - 拦截前 - Action处理 - 拦截后 -过滤后。个人认为过滤是一个横向的过程,首先把客户端提交的内容进行过滤(例如未登录用户不能访问内部页面的处理);过滤通过后,拦截器将校验用户提交的数据,做一些前期的数据处理;接着把处理后的数据发给对应的Action,Action处理完成返回后Model 和 View,拦截器还可以做其它过程,再向上返回到过滤器的后续操作。
使用原则
对整个流程清楚之后,然后就是各自的使用,在使用之前应该有一个使用规则,为什么这么说?因为有些功能比如判断用户是否登录,既可以用过滤器,也可以用拦截器,用哪一个才是合理的呢?那么如果有一个原则,使用起来就会更加合理。实际上这个原则是有的:把整个项目的流程比作一条河,那么监听器的作用就是能够听到河流里的所有声音,过滤器就是能够过滤出其中的鱼,而拦截器则是拦截其中的部分鱼,并且作标记。所以当需要监听到项目中的一些信息,并且不需要对流程做更改时,用监听器;当需要过滤掉其中的部分信息,只留一部分时,就用过滤器;当需要对其流程进行更改,做相关的记录时用拦截器。