Java开发学习笔记之九:过滤器

时间:2021-07-21 22:12:51

一、过滤器的概念
  过滤器是介于客户和servlet的一层Web构件,它可以拦截来自客户的对Web资源的请求或servlet对客户的响应。过滤器(filter)是能够对请求和响应的头属性(header)和内容体(body)进行操作的特殊Web构件。与一般Web构件不同的是,过滤器自身不直接生成Web响应,若干个过滤器可以指向对一个Web资源的请求和请求响应进行作用。
  过滤器与servlet之间是多对多的关系,一个过滤器可以对多个servlet的请求和响应进行过滤,一个servlet也可以被多个过滤器作用,多个过滤器对一个servlet的过滤构成一个过滤器链。
  过滤器主要功能有:
1.对Web请求进行分析,对输入数据进行预处理;
2.阻止请求和响应的早先;
3.根据功能改动请求的头信息和数据体;
4.和其他Web资源协作。
  然而,这些功能在servlet中都可以实现。为什么还要多出一个过滤器的来呢。答案是在编程结构设计上的考虑。过滤器主要用于一些通用性的操作,其特点是通用生和可移植性,如安全保护,运行记录,数据加密解密以及XML转化等等。

二、过滤器的使用方法
  有关过滤器的API包括javax.servlet.Filter,javax.servlet.FilterConfig,FilterChain等几个接口。下例程序实现了一个过滤器接口。
public final class SimpleFilter implements Filter{
  private FilterConfig fconfig = null;
  public void init(FilterConfig fconfig)
  throws ServletException{
    this.fconfig = fconfig
  }

  public void destroy(){
    fconfig = null;
  }
 
  public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
  throws IOException,ServletException{
    ...
    chain.doFilter(request,response);
    ...
  }
}

  方法init()和destroy()初始化和清除。当Web容器接收到servlet或JSP的请求时,如果该servlet或JSP用到一个filter时,Web容器就会调用这个过滤的折doFilter方法。doFilter方法实现了过滤器对请求和响应的操作功能。这个方法前两个参数分别是请求和响应对象。第三个参数chain是过滤器链。
  当一个servlet或JSP有多个过滤器时,这些过滤器形成一个过滤器链,它们依次对请求和响应进行处理。在一个过滤器的doFilter方法中调用FilterChain的doFilter方法,这样的结果是激活过滤器链中的下一个过滤器。过滤器的末端是servlet或JSP。如果当前过滤器是过滤器链中的最后一个,则FitlerChain对象的doFilter执行后调用的是servlet或JSP。如果过滤器链中的任何一个过滤器未调用FilterChain对象的doFilter方法,则请求中断到那个过滤器为止,目标servlet或JSP将收不到请求。 可以在chain.doFilter(request,response)这一行之前对Resquest进行处理,而在此行之后对由servlet返回的Response进行处理 。

三、Web.xml文件中关于过滤器的配置说明
  如下web.xml:
<? xml version="1.0" encoding="ISO-8859-1"?>
<! DOCTYPE web-app PUBLIC
"-Sun Microsystems,Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
...
<filter>
<icon>filter.jpg</icon>
<filter-name>SimpleFilter</filter-name>
<display-name>ASimpleFilter</filter-name>
<description>The first filter example</description>
<filter-class>fey.filters.SimpleFilter</filter-class>
<init-param>
<param-name>param1</param-name>
<param-value>value1</param-value>
</init-param>
...
<filter-mapping>
<filter-name>SimpleFilter</filter-name>
<url-pattern>/header/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SimpleFilter</filter-name>
<url-pattern>/headerinfo</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SimpleFilter</filter-name>
<servlet-name>SimpleServlet</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>SimpleFilter</filter-name>
<servlet-name>FormParam</servlet-name>
</filter-mapping>
...
</web-app>
其中,<icon>filter.jpg</icon>指定了在编程工具中用来显示该过滤器的图标;
<filter-name>SimpleFilter</filter-name>定义了过滤器的名称;
<display-name>ASimpleFilter</filter-name>定义了该过滤器的编程工具中的显示名称;
<description>The first filter example</description>定义了该过滤器的注解;
<filter-class>fey.filters.SimpleFilter</filter-class>定义了该过滤器的类名;
<init-param>...</init-param>这一段定义了过滤器的初始化参数,这些参数可以在FilterConfig的getInitParameter方法中取得。
在以上这些标记中,只有<filter-name>...</filter-name>和<filter-mapping>...</filter-mapping>是必须的,其它都是可选。

<filter-mapping>...</filter-mapping>标记表明了一个过滤器和Web资源(servlet,JSP)的关系,其中:
<filter-name>...</filter-name>指定过滤器的名称
<url-pattern>...</url-pattern>设定过滤器所过滤的网址样式
<servlet-name>...</servlet-name>直接设定过滤器过滤的servet名称(当然此servlet必须在web.xml中有定义)。