Servlet Filter解析

   Servlet Filter(过滤器)是小型的web组件,它能够处理传入的请求和传出的响应。它能够在一个request到达Servlet之前预处理request,也可以在离开Servlet时处理response。它具有高度的透明性,无需更改应用程序代码,就可以根据需要添加、修改或从应用程序中将它删除。

   一个Filter 包括: 

  • 在servlet被调用之前截获; 
  • 在servlet被调用之前检查servlet request; 
  • 根据需要修改request头和request数据; 
  • 根据需要修改response头和response数据; 
  • 在servlet被调用之后截获. 

创建一个Filter我们只要implements Filter接口然后重写Filter接口中的三个方法就可以了,下面创建一个我们自己的Filter名字叫MyFilter:

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class MyFilter implements Filter {

	public void destroy() {
		// TODO Auto-generated method stub
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("enter filter....");
		chain.doFilter(request, response);
		System.out.println("out  filter....");
	}

	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

 在创建完MyFilter类之后,需要在web.xml文件加入相应代码进行部署:

  <filter>
    <display-name>MyFilter</display-name>
    <filter-name>MyFilter</filter-name>
    <filter-class>cookie.MyFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

 这样配置完之后,当我们再通过浏览器去访问的时候,所有的请求都会先经过MyFilter,首先执行doFilter方法中的System.out.println("enter filter...."); 然后执行chain.doFilter(request, response);如果还有其它的Filter则会继续调用其它的Filter,如果没有其它的Filter则调用所请求的Servlet,在调用完Servlet之后就执行System.out.println("out  filter....");然后请求结束。

   如果要建立多个Filter写法也和上面的一样创建另一个Filter类,在web.xml中进行部署。在这里如果项目中有多个Filter,它们的执行顺序是怎么区别的呢?通过测试发现,服务器会通过web.xml中Filter部署的顺序来决定每个Filter执行的顺序:

  <filter>
    <display-name>MyFilter2</display-name>
    <filter-name>MyFilter2</filter-name>
    <filter-class>cookie.MyFilter2</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>MyFilter2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter>
    <display-name>MyFilter</display-name>
    <filter-name>MyFilter</filter-name>
    <filter-class>cookie.MyFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

   上面有两个Filter,MyFilter和MyFilter2但MyFilter2在web.xml中是放在MyFilter的前面的,所以当执行的时候是会先执行MyFilter2。

   通过源码可以看到FilterChain接口的实现类ApplicationFilterChain有个数组filters,这个里面放的就是我们所定义的所有Filter。当启动服务器的时候服务器通过web.xml所定义的<filter>标签中的内容去实例化每个过渡器,并把每个实例添加到filters这个数组中。

final class ApplicationFilterChain  implements FilterChain, CometFilterChain{
 private static final ThreadLocal lastServicedRequest;
 private static final ThreadLocal lastServicedResponse;
 public static final int INCREMENT = 10;
 private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];

 

 

 

猜你喜欢

转载自notebookdong.iteye.com/blog/1856461
今日推荐