Tomcat 7源码学习笔记 -8 Filter过滤器解读

1.过滤器的主要功能是允许我们在request转给某个资源之前(比如:html文件,servlet,JSP文件,图片文件,excel文件等等)做一些事情,然后在response返回给客户端之前做一些事情。功能上有些类似于防火墙,对入口和出口进行严格控制。

public class MyFilter implements Filter {

//tomcat启动,或者context重新加载的时候调用init(先destroy再init)
public void init(FilterConfig filterConfig) throws ServletException {
  System.out.println("MyFilter init...");
}

public void doFilter(ServletRequest request, ServletResponse response,
   FilterChain chain) throws IOException, ServletException {
  //request到达的时候执行下面的代码
  System.out.println("MyFilter request>>>>>>>>>>>>");
  
  //转给过滤器链中的下一个filter,如果是最后一个filter,调用要访问的资源
  chain.doFilter(request,response);
  
  //要访问的资源访问完以后,response到达的时候执行下面的代码
  System.out.println("MyFilter response>>>>>>>>>>>>");
}
//tomcat关闭或者context重新加载的时候调用destroy
public void destroy() { 
  System.out.println("MyFilter destroy...");
}

}

2.filter的配置方法

web.xml

通过url匹配:

<filter>
    <filter-name>My Filter</filter-name>
    <filter-class>MyFilter</filter-class>
    <init-param>
      <param-name>debug</param-name>
      <param-value>0</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>My Filter</filter-name>
<!-- url匹配规则 -->
    <url-pattern>/*</url-pattern>  
<!-- filter对应的请求方式,默认是REQUEST -->
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

通过servlet名匹配:

<filter>
    <filter-name>My Filter</filter-name>
    <filter-class>MyFilter</filter-class>
    <init-param>
      <param-name>debug</param-name>
      <param-value>0</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>My Filter</filter-name>
<!-- 根据url匹配到MyServlet的时候,执行My Filter -->
    <servlet-name>MyServlet</servlet-name>  
<!-- filter对应的请求方式,默认是REQUEST -->
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

3.过滤器链

1)request到达以后,实际匹配到的过滤器可能有一个,也可能有多个,多个的时候,会形成一个过滤器链,过滤器的执行顺序和web.xml中filter-mapping的配置的先后顺序一致,写在前面的先执行,写在后面的后执行。

2)每个过滤器执行完以后会调用chain.doFilter(request,response);从而调用下一个过滤器的doFilter方法。(其实此时执行到的只是每个过滤器中chain.doFilter(request,response);之前的代码)

3)当所有的匹配到的过滤器都执行完以后,将调用具体访问的资源,比如servlet,或者jsp。

4)请求的资源执行结束后,response返回的时候,再次调用匹配到的过滤器。调用顺序和request到达时的调用顺序正好相反。(此时执行的是每个过滤器中chain.doFilter(request,response);之后的代码)

如果在过滤器的doFilter前后,以及访问的servlet的doGet中事先写入打印调试信息的话,在浏览器中提交某个get请求的话,在控制台会看到下面的打印信息:

MyFilter1request>>>>>>>>>>>>

MyFilter2request>>>>>>>>>>>>

MyFilter3request>>>>>>>>>>>>

MyServletdoGet>>>>>>>>>>>>

MyFilter3response>>>>>>>>>>>>

MyFilter2response>>>>>>>>>>>>

MyFilter1response>>>>>>>>>>>>

对应的调用顺序如下:

客户端发出request-->MyFilter1-->MyFilter2-->MyFilter3-->MyServlet-->MyFilter3-->MyFilter2-->MyFilter1

-->客户端获得response

相关推荐