filter和interceptor

2013-11-15 16:31:58 [内容并不准确,仅用于加深理解]

 

过滤器:

Web项目启动时,web容器会加载web.xml中配置的filter并调用其init()进行初始化.

当有request到达,会根据匹配规则把符合的filter放入filterChain.按照web.xml中的配置顺序来执行. Filter的doFilter()方法中,把filterChain的下一链(chain.doFilter())或者最终执行的资源请求包裹(invoke()),你可以在这前后加代码,修改request或者response. 还可以不转入下一链或者最终的资源,直接中断或者转到别的资源.

 

释疑:

  1. 过滤响应

问题:当StrutsPrepareAndExcuteFilter执行访问的最终servlet时,writer.write()实际上已经把对响应内容输出到浏览器了,所以返回filterChain之前的filter里,虽然可以在doFilter()方法后对response进行改变,但是已经不起作用了.所以,对response过滤是没有意义的

修改response,需要重写ResponseWrapper,这里response生成的最终响应内容先不输出,而是在ResponseWrapper里面进行缓存,filter就可以对它进行修改了,然后再需要的filter把response的响应内容输出出去.

示例: http://www.cnblogs.com/CaiBaoZi/archive/2013/06/05/3120091.html

 

  1. 过滤策略

问题:Filter可以过滤对资源的请求,但是有个问题,如果在filter或者最终的servlet里面进行了转发,那么也是会产生对资源的请求的,这样会不会死循环过滤呢?

 

对于servlet2.4及以上,filter不会截取server内部的请求,比如forward,所以需要配置dispatcher属性。

指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截。
REQUEST:
当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问或ERROR情况时,那么该过滤器就不会被调用。
INCLUDE:
如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
FORWARD:
如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
ERROR:
如若在A.jsp页面page指令中指定了error属性=examError.jsp,那么A.jsp中若出现了异常,会跳转到examError.jsp中处理。而在跳转到examError.jsp时,若过滤器配置了ERROR的dispather那么则会拦截,否则不会拦截。

        资料http://www.2cto.com/kf/201210/162383.html:

 

 

拦截器:

  动态拦截Action调用的对象,通过发射机制实现
  拦截器栈(Interceptor Stack)。Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。 

  Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的    拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器

 

 

拦截器与过滤器的区别 :

  过滤器是servlet里面的概念。拦截器是action里面的概念。

  1. 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
  2. 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。(过滤器的chain需要servlet容器实现,且过滤器是根据url实现过滤,url需要servlet解析)
  3. 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  4. 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
posted @ 2013-11-15 16:35  helloworld~  阅读(1363)  评论(0编辑  收藏  举报