以前老是弄混这二者,今天看了几篇文章,小结一下在这里。java
Filter介绍
Filter能够认为是Servlet的一种“增强版”,它主要用于对用户请求进行预处理,也能够对HttpServletResponse进行后处理,是个典型的处理链。Filter也能够对用户请求生成响应,这一点与Servlet相同,但实际上不多会使用Filter向用户请求生成响应。使用Filter完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行预处理并生成响应,最后Filter再对服务器响应进行后处理。web
Filter有以下几个用处。spring
- 在HttpServletRequest到达Servlet以前,拦截客户的HttpServletRequest。
- 根据须要检查HttpServletRequest,也能够修改HttpServletRequest头和数据。
- 在HttpServletResponse到达客户端以前,拦截HttpServletResponse。
- 根据须要检查HttpServletResponse,也能够修改HttpServletResponse头和数据。
Filter有以下几个种类。编程
- 用户受权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求。
- 日志Filter:详细记录某些特殊的用户请求。
- 负责解码的Filter:包括对非标准编码的请求解码。
- 能改变XML内容的XSLT Filter等。
- Filter能够负责拦截多个请求或响应;一个请求或响应也能够被多个Filter拦截。
建立一个Filter只需两个步骤安全
- 建立Filter处理类
- web.xml文件中配置Filter
建立Filter必须实现javax.servlet.Filter接口,在该接口中定义了以下三个方法。服务器
- void init(FilterConfig config):用于完成Filter的初始化。
- void destory():用于Filter销毁前,完成某些资源的回收。
- void doFilter(ServletRequest request,ServletResponse response,FilterChain chain):实现过滤功能,该方法就是对每一个请求及响应增长的额外处理。该方法能够实现对用户请求进行预处理(ServletRequest request),也可实现对服务器响应进行后处理(ServletResponse response)—它们的分界线为是否调用了chain.doFilter(),执行该方法以前,即对用户请求进行预处理;执行该方法以后,即对服务器响应进行后处理。
Interceptor介绍
拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问以前,进行拦截,而后在以前或以后加入某些操做。拦截是AOP的一种实现策略。函数
在WebWork的中文文档的解释为—拦截器是动态拦截Action调用的对象。它提供了一种机制可使开发者能够定义在一个Action执行的先后执行的代码,也能够在一个Action执行前阻止其执行。同时也提供了一种能够提取Action中可重用的部分的方式。编码
拦截器将Action共用的行为独立出来,在Action执行先后执行。这也就是咱们所说的AOP,它是分散关注的编程方法,它将通用需求功能从不相关类之中分离出来;同时,可以共享一个行为,一旦行为发生变化,没必要修改不少类,只要修改这个行为就能够。url
拦截器将不少功能从咱们的Action中独立出来,大量减小了咱们Action的代码,独立出来的行为就有很好的重用性。spa
当你提交对Action(默认是.action结尾的url)的请求时,ServletDispatcher会根据你的请求,去调度并执行相应的Action。在Action执行以前,调用被Interceptor截取,Interceptor在Action执行先后执行。
建立Interceptor必须实现com.opensymphony.xwork2.interceptor.Interceptor接口,该接口定义了以下三个方法。
- void init():在该拦截器被实例化以后,在该拦截器执行拦截以前,系统将回调该方法。对于每一个拦截器而言,其init()方法只执行一次。所以,该方法的方法体主要用于初始化资源。
- void destory():该方法与init()方法对应。在拦截器实例被销毁以前,系统将回调该拦截器的destory方法,该方法用于销毁在init方法里打开的资源。
- String intercept(ActionInvocation invocation):该方法是用户须要实现的拦截动做。就像Action的execute方法同样。intercept方法会返回一个字符串做为逻辑视图。若是该方法直接返回了一个字符串,系统会将跳转到该逻辑视图对应的实际视图资源,不会调用被拦截的Action。该方法的ActionInvocation参数包含了被拦截的Action的引用,能够经过调用该参数的invoke方法,将控制权转给下一个拦截器,或者转给Action的execute方法(若是该拦截器后没有其余拦截器,则直接执行Action的execute方法)。
Filter和Interceptor的区别
- Filter是基于函数回调(doFilter()方法)的,而Interceptor则是基于Java反射的(AOP思想)。
- Filter依赖于Servlet容器,而Interceptor不依赖于Servlet容器。
- Filter对几乎全部的请求起做用,而Interceptor只能对action请求起做用。
- Interceptor能够访问Action的上下文,值栈里的对象,而Filter不能。
- 在action的生命周期里,Interceptor能够被屡次调用,而Filter只能在容器初始化时调用一次。
Filter和Interceptor的执行顺序
过滤前-拦截前-action执行-拦截后-过滤后
一些理解:
但凡跟servlet有关——参数url-pattern指定的目标,均可以用filter。
至于interceptor,一般的场景是利用反射来管理某个类的方法。好比但凡Service的save.*和delete.*的方法都必须开启事务处理,全部Dao方法抛出异常时统一处理等。
可是Action/controller比较特殊,由于它既是类的方法,又是映射到某个url上,容易让人困惑。
好比登录校验,没有登录的所有跳转到一个错误页面
好比后台安全校验,安全校验不经过的跳转到一个错误页面
其实两种均可以,
- 用filter过滤url。拿原始的web资源比较方便。
- 用interceptor过滤方法。拿request和response不必定方便,但访问spring的资源方便。