`
g21121
  • 浏览: 685525 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java中的filter

 
阅读更多

        上一篇说了下servlet,不知道对各位有没有什么帮助,现在说下filter吧。
        Filter也是servlet包下的一个接口,中文意思是“过滤器”,其他语言也能时常看到这个单词,它的主要作用就是过滤,对!过滤你想过滤的东西,例如:文件,http请求地址,字符编码等等(在actionScript中filter极易编写,功能也非常强大)。
        API地址:http://docs.oracle.com/javaee/5/api/
        下面是api中对于filter的介绍

filter api 写道
A filter is an object that performs filtering tasks on either the request to a resource (a servlet or static content), or on the response from a resource, or both.

Filters perform filtering in the doFilter method. Every Filter has access to a FilterConfig object from which it can obtain its initialization parameters, a reference to the ServletContext which it can use, for example, to load resources needed for filtering tasks.

Filters are configured in the deployment descriptor of a web application

Examples that have been identified for this design are
1) Authentication Filters
2) Logging and Auditing Filters
3) Image conversion Filters
4) Data compression Filters
5) Encryption Filters
6) Tokenizing Filters
7) Filters that trigger resource access events
8) XSL/T filters
9) Mime-type chain Filter
Since:
Servlet 2.3

        从这个介绍可以看出filter是从servlet2.3版本才加入的,用来执行过滤任务的组件,这里值得注意的是filter并不是一个servlet,它会在servlet执行前执行以起到过滤作用。
        Api中还列举了下面这些可以过滤的例子,当然不仅仅局限于这些:

1)身份验证过滤器
2)记录和审计过滤器
3)图像转换过滤器
4)数据压缩过滤器
5)加密过滤器
6)标记化过滤器
7)过滤器,触发资源访问事件
8)XSL/ T过滤器
9)MIME型连锁滤波器

 

        下面分析下filter相关的接口。
        Filter接口:filter是servlet包中的一个接口,它其中只有三个方法,doFilter方法最重要,在这个方法里写你的关键代码。

/**
* 初始化方法
 */
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
 * 过滤执行方法,你的代码放在这个方法中
 */
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
		
}
/**
 * 默认销毁方法
 */
public void destroy() {
	
}

 

        FilterChain 接口:中文意思是过滤器调用链,FilterChain 只有一个方法,通过chain. doFilter会调用下一个filter。

public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
		
} 

        FilterConfig接口:这是filter的相关参数配置接口,可以通过这个接口获取到filter的相关信息,在此就不介绍了。

 

        现在就分析下filter的工作原理和流程:
        要弄清filter和servlet的调用流程不如自己建立一个工程,打印些日志就非常明了了。
        1.首先建立一个web工程filter_test,然后建立一个servlet起名为TestServlet。

  <!-- servlet 配置 -->
  <servlet>
    <description>test servlet</description>
    <display-name>test servlet</display-name>
    <servlet-name>testServlet</servlet-name>
    <servlet-class>TestServlet</servlet-class>
  </servlet>
  <!-- servlet请求映射配置 -->
  <servlet-mapping>
    <servlet-name>testServlet</servlet-name>
    <url-pattern>/servlet/testServlet</url-pattern>
  </servlet-mapping>

 

        TestServlet的实现:

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 类描述:测试servlet
 * @author ming.li<br/> 
 *		<a href="http://g21121.iteye.com">iteye bolg</a>
 * @time 2012-2-2 下午04:10:46
 */
public class TestServlet extends HttpServlet {

	/**
	 * 默认构造方法
	 */
	public TestServlet() {
		System.out.println("TestServlet:构造方法");
	}
	/**
	 * 默认初始化方法
	 */
	public void init() throws ServletException {
		System.out.println("TestServlet:初始化方法");
	}

	/**
	 * 默认get请求处理方法
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("TestServlet:get请求处理方法");
		response.sendRedirect("http://www.baidu.com/");
	}

	/**
	 * 默认post请求处理方法
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("TestServlet:post请求处理方法");
	}

	/**
	 * 默认销毁方法
	 */
	public void destroy() {
		System.out.println("TestServlet:销毁方法");
	}

}

 2.然后创建第一个filter。
Filter在web.xml中的配置:

  <!-- 第一个filter -->
  <filter>
  	<description>test fileter for TestServlet 1</description>
  	<filter-class>TestFilter</filter-class>
  	<filter-name>testFilter</filter-name>
  </filter>
  <!-- filter映射配置 -->
  <filter-mapping>
  	<filter-name>testFilter</filter-name>
  	<servlet-name>testServlet</servlet-name>
  	<url-pattern>/servlet/</url-pattern>
  	<!-- dispatcher是servlet2.4才加入的的,这点需要注意一下 -->
  </filter-mapping>

 

•在<filter-mapping>配置中,<servlet-name>标签中填写的就是我们要处理的servlet,也就是testServlet,注意这里填写的是servlet-name而不是类名称。
•<url-pattern>标签中填写的就是拦截的请求链接,即在该请求下才调用filter。
•<dispatcher>是在servlet2.4才加入的,里面有
实现filter:

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;

/**
 * 类描述:第一个filter
 * @author ming.li<br/> 
 *		<a href="http://g21121.iteye.com">iteye bolg</a>
 * @time 2012-2-2 下午04:21:29
 */
public class TestFilter implements Filter {
	
	/**
	 * 默认初始化方法
	 */
	public void init(FilterConfig fc) throws ServletException {
		System.out.println("TestFilter:初始化方法");
	}
	/**
	 * 默认处理方法
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("TestFilter:处理方法,doFilter之前");
		chain.doFilter(request, response);
		System.out.println("TestFilter:处理方法,doFilter之后");
	}
	/**
	 * 默认销毁方法
	 */
	public void destroy() {
		System.out.println("TestFilter:销毁方法");
	}

}

 

3.运行项目。
运行过程中我们发现控制台打印了这一句话:TestFilter:初始化方法
说明filter的初始化在启动服务器的时候已经完成了。
然后我们打开浏览器在地址栏里敲入地址:http://localhost:8080/filter_test/servlet/testServlet
控制台打印的信息是:

TestServlet:构造方法
TestServlet:初始化方法
TestFilter:处理方法,doFilter之前
TestServlet:get请求处理方法
TestFilter:处理方法,doFilter之后

 从这个信息打印的顺序我们可以大致分析出filter和servlet的工作流程。
1).servlet的构造方法
2). servlet的初始化方法
3). filter的doFilter方法, chain.doFilter之前的内容
4). servlet对应的请求方法(get post delete put)
5). filter的doFilter方法, chain.doFilter之后的内容
4.此时我再添加一个filter,这个filter同样会处理servlet,看看这两个filter之间有什么联系。
 命名另一个filter为OtherTestFilter,web.xml配置为:

  <!-- 第二个filter -->
  <filter>
  	<description>test fileter for TestServlet 2</description>
  	<filter-class>OtherTestFilter</filter-class>
  	<filter-name>otherTestFilter</filter-name>
  </filter>
  <!-- filter映射配置 -->
  <filter-mapping>
  	<filter-name>otherTestFilter</filter-name>
  	<servlet-name>testServlet</servlet-name>
  	<url-pattern>/servlet/</url-pattern>
  </filter-mapping>

 

OtherTestFilter实现为:

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;

/**
 * 类描述:第二个测试filter
 * @author ming.li<br/> 
 *		<a href="http://g21121.iteye.com">iteye bolg</a>
 * @time 2012-2-3 上午10:07:21
 */
public class OtherTestFilter implements Filter {

	/**
	 * 默认初始化方法
	 */
	public void init(FilterConfig fc) throws ServletException {
		System.out.println("OtherTestFilter:初始化方法");
	}
	/**
	 * 默认处理方法
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("OtherTestFilter:处理方法,doFilter之前");
		chain.doFilter(request, response);
		System.out.println("OtherTestFilter:处理方法,doFilter之后");
	}
	/**
	 * 默认销毁方法
	 */
	public void destroy() {
		System.out.println("OtherTestFilter:销毁方法");
	}

}

 5.我们依旧打开http://localhost:8080/filter_test/servlet/testServlet

这个地址,看控制台打印日志是什么:

 控制台日志
TestServlet:构造方法
TestServlet:初始化方法
TestFilter:处理方法,doFilter之前
OtherTestFilter:处理方法,doFilter之前
TestServlet:get请求处理方法
OtherTestFilter:处理方法,doFilter之后
TestFilter:处理方法,doFilter之后

 结合前面的分析,我们发现如果有多个filter处理同一个servlet的时候,他们的执行顺序如下图


 所以经过上面的分析我们不难看出,FilterChain的作用就是以数组形式储存储存要调用的filters,然后在filter中调用chain.doFilter(),执行列表中下一个filter中doFilter()之前代码,以此类推,是不是已经晕了,呵呵。

了解了filter的工作原理和工作流程,我们就能更简单的开发对应的filter了,具体例子,大家可以搜索一下,网上有很多。

  • 大小: 74.7 KB
4
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics