Filter原理及应用

 
  •        filter功能

       使用户可以改变一个request和修改一个response。Filter不是一个servlet,他不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开servlet时处理response。换种说法,filter其实是一个servlet chaining(servlet链)。

      一个filter包括:

1、  在servlet被调用之前截获

2、  在servlet被调用之前检查servlet request。

3、  根据需要修改request头和request数据

4、  根据需要修改response头和response数据

5、  在servlet被调用之后截获。

       你能够配置一个filter到一个或多个servlet;单个servlet或servlet组能够被多个filter使用。几个实用的filter包括:权限控制(可以防止URL跳转),Session控制,Web Cache(如比较大的图片加载时),用户辨认filter,日志filter,审核filter,加密filter,符号filter,能改变xml内容的XSLT filter等

  • filter原理

       

 

       当客户端发出web资源的请求时,web服务器根据应用程序配置文件设置的过滤规则进行检查,若客户请求满足过滤规则,则对客户请求/响应进行拦截,对请求头和请求数据进行检查或改动,并依次通过过滤器链,最后把请求/响应交给请求的web资源处理。请求信息在过滤器链中可以被修改,也可以根据条件让请求不发往资源处理器,并直接向客户机发回一个响应。当资源处理器完成了对资源的处理后,响应信息将逐级逆向返回。同样,这个过成功,用户可以修改相应信息,从而完成一定的任务。

 

      当一个请求符合多个过滤器的过滤条件时,服务器会按照web.xml中过滤器定义的先后循环组装成一条链,然后依次执行其中的doFilter()方法。执行顺序为:执行第一个过滤器的chain.doFilter()之前的代码,第二个过滤器的chain.doFilter()之前的代码,请求的资源,第二个过滤器的chain.doFilter()之后的代码,第一个过滤器的chain.doFilter()之后的代码,最后返回响应。如图

  • filter注意事项:

filter技术在servlet2.3规范中加入的,大部分的jsp/servlet容器都支持

filter和ADP(Aspect Oriented Programming)面向切面的编程

Filter可以看做是一种横切的技术

Filter体现了一个模式,责任链模式

Servlet体现了一个模式模板方法模式

Java IO体现了装饰模式

Filter其实提供了一种声明式服务,声明式服务非常强大,它具有可插拔的能力

Filter其实对Request和Response请求进行了 拦截

Filter只对Post请求起作用

  • filter实现

       所有的过滤器都必须实现Filter接口。该接口定义了init,doFilter(),destroy()三个方法。

       (1) public void init (FilterConfig filterConfig) throws   ServletException.
            当开始使用servlet过滤器服务时,Web容器调用此方法一次,为服务准备过滤器;然后在需要使用过滤器的时候调用doFilter(),传送给此方法的FilterConfig对象,包含servlet过滤器的初始化参数。
      (2)public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
                                              throws java.io.IOException,ServletException.

          每个过滤器都接受当前的请求和响应,且FilterChain过滤器链中的过滤器(应该都是符合条件的)都会被执行。doFilter方 法中,过滤器可以对请求和响应做它想做的一切,通过调用他们的方法收集数据,或者给对象添加新的行为。过滤器通过传送至 此方法的FilterChain参数,调用chain.doFilterO将控制权传送给下一个过滤器。当这个调用返回后,过滤器可以在它的 Filter方法的最后对响应做些其他的工作。如果过滤器想要终止请求的处理或得到对响应的完全控制,则可以不调用下一个过滤 器,而将其重定向至其它一些页面。当链中的最后一个过滤器调用chain.doFilterO方法时,将运行最初请求的Servlet。
      (3)public void destroy()
        一旦doFilterO方法里的所有线程退出或已超时,容器调用此方法。服务器调用destoryO以指出过滤器已结束服务,用于释放过滤器占用的资源。

  • 代码示例
//设置统一的字符集编码控制类   
public class CharsetEncodingFilter implements Filter {  
      
    public void destroy() {  
    }  
  
    public void doFilter(ServletRequest servletRequest,  
            ServletResponse servletResponse, FilterChain filterChain)  
            throws IOException, ServletException {  
        //设置字符集
        System.out.println("begin"); 
        request.setCharacterEncoding("GB18030");
        //继续执行
  
        chain.doFilter(request, response);
        System.out.println("end");    }  
  
    public void init(FilterConfig filterConfig) throws ServletException {  
           }  
  
}  

配置文件

<filter>  
        <filter-name>CharsetEncodingFilter</filter-name>  
        <filter-class>kane.CharsetEncodingFilter</filter-class>  
        <init-param>  
            <param-name>charEncode</param-name>  
            <param-value>GB18030</param-value>  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>CharsetEncodingFilter</filter-name>  
        <url-pattern>*.jsp</url-pattern>  
    </filter-mapping>  



 

 

 

 

posted @ 2012-03-15 15:31  转航  阅读(368)  评论(0编辑  收藏  举报