zoukankan      html  css  js  c++  java
  • Filter过滤器机制

    tomcat内部过滤器采用了责任链的设计模式,

    Tomcat的过滤器主要由Filter、FilterChain组成,FilterChain包含一个Filter数组.当Wrapper执行FilterChain的doFilter(request,response)方法时,FilterChain首先调用第一个Filter的doFilter(request,response,filterchain)方法,当第一个filter做完过滤操作后,它又会调用filterchain的doFilter方法,此时filterchain的当前filter已变为第二个filter,第二个filter又执行dofilter方法,依此类推,直至所有过滤器都执行完毕。

    1. public interface Filter {   
    2.         .....          
    3.         //执行过滤   
    4.         public void doFilter ( ServletRequest request, ServletResponse response, throws IOException, ServletException;   
    5.   
    6. }   
    7.   
    8. public interface FilterChain {   
    9.     public void doFilter ( ServletRequest request, ServletResponse response ) throws IOException, ServletException;   

    FilterConfig接口检索过滤器名、初始化参数以及活动的Servlet上下文。ApplicationFilterConfig是其实现类

    ApplicationFilterChain在catalina.jar的org.apache.catalina.core包中

    1. class ApplicationFilterChain implements FilterChain {   
    2. ..................
    3.    private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
    4.   private int pos = 0;
        private int n = 0;
    5.    //pos为当前filter的所在位置,n为filters数组的长度   
    6.    if (pos < n) {   
    7.             //pos++执行后,把filterchain的当前filter指向下一个   
    8.             ApplicationFilterConfig filterConfig = filters[pos++];   
    9.             Filter filter = null;   
    10.             try {   
    11.                 filter = filterConfig.getFilter();   
    12.   
    13.                 //filter执行过滤操作   
    14.                 filter.doFilter(request, response, this);   
    15.             }   
    16.             ...   
    17.    }   
    18. }  
    19.  

    20. 实例如下:

    21. class SampleFilter implements Filter {   
    22.       ........   
    23.       public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)   
    24.         throws IOException, ServletException {   
    25.          //do something    
    26.          .....   
    27.          //request, response传递给下一个过滤器进行过滤   
    28.          chain.doFilter(request, response);   
    29.     }   
    30.          
    31. }

    先描述tomcat的方法调用序列。

          具体过程如下:
                    (1)connector 创建 request 和 response 对象;
                    (2)connector 调用 StandardContext 实例的 invoke 方法;
                    (3)StandardContext 接着调用其 pipeline 的 invoke 方法,StandardContext 中 pipeline 的 basic valve 是
      StandardContextValve,因此,StandardContext 的 pipeline 会调用 StandardContextValve 的 invoke 方法;
                    (4)StandardContextValve 的 invoke 方法获取 wrapper 处理请求,调用 wrapper 的 invoke 方法;
                    (5)StandardWrapper 是 Wrapper 接口的标准实现,StandardWrapper 实例的 invoke 方法会调用其
      pipeline 的 invoke 方法;
                    (6)StandardWrapper 的 pipeline 中的 basic valve 是 StandardWrapperValve,因此,会调用其 invoke 方
     法,StandardWrapperValve 调用 wrapper 的 allocate 方法获取 servlet 实例;
                    (7)allocate 方法调用 load 方法载入 servlet 类,若已经载入,则无需重复载入;
                    (8)load 方法调用 servlet 的 init 方法;
                    (9)StandardWrapperValve 调用 servlet 的 service 方法。

    StandardWrapperValve中的主要代码如下:

    1.    ApplicationFilterChain filterChain =  
    2.        createFilterChain(request, servlet);  
    3.    /*略  
    4.    String jspFile = wrapper.getJspFile();  
    5.    if (jspFile != null)  
    6.        sreq.setAttribute(Globals.JSP_FILE_ATTR, jspFile);  
    7.    else  
    8.        sreq.removeAttribute(Globals.JSP_FILE_ATTR);  
    9.    if ((servlet != null) && (filterChain != null)) {  
    10.        filterChain.doFilter(sreq, sres);  
    11.    }  
    12.    sreq.removeAttribute(Globals.JSP_FILE_ATTR); 

    在StandardWrapperValve的invoke中(也就是上面贴的代码),第10行的代码就是调用servlet的入口,传说中的doFilter()。

  • 相关阅读:
    技术列表
    常用软件开发工具
    EXCEL数据导入SQL2008相关操作
    点点滴滴
    揪出ASP.NET 2.0四大“插件”的总后台 ASPNETDB
    古人说
    好点子都是偷来的:史上最感性的60堂创新课读书摘要
    我是怎么割韭菜的:一个骗子的悔过与自白读书摘要
    人生如我读书摘要
    德米安:彷徨少年时读书摘要
  • 原文地址:https://www.cnblogs.com/shz365/p/6297707.html
Copyright © 2011-2022 走看看