Servlet和JSP过滤器是一种用在servlet和jsp编程中的java类,其使用目的如下:

(一)在客户访问后台资源之前拦截客户请求

(二)在资源被送到客户端之前加以控制


规范所建议的过滤器有多种:

(一)验证类过滤器

(二)数据压缩类过滤器

(三)加密过滤器

(四)触发事件类过滤器

(五)图片转换类过滤器

(六)日志记录和监听过滤器

(七)MIME-TYPE Chain类过滤器

(八)令牌类过滤器

(九)转换XML内容的XSL/T过滤器

过滤器需要部署在描述文件web.xml中,可以映射到所写应用的servlet、jsp页面或其它特定URL上。部署描述文件web.xml可以在web应用的WEB-INF目录下找到。

在JSP容器启动web应用时,它会自动把你在部署描述符中声明的每一个过滤器创建一个实例。过滤器执行的顺序和你在web.xml中声明的顺序一致。


过滤器对象中的方法

过滤器只是一个实现了javax.servlet.Filter接口的简单java类。接口javax.servlet.Filter定义了3个方法:

序号

方法& 描述

1

public void doFilter (ServletRequest, ServletResponse, FilterChain)
该方法在客户端请求及服务器端回复时都将被自动调用

2

public void init(FilterConfig filterConfig)
初始化配置参数,在doFilter()方法之前被调用

3

public void destroy()
结束过滤器,doFilter()方法完成后被调用

过滤器示例

以下示例的作用是,在客户端每次访问JSP页面时,控制台会打印出客户的ip地址和访问时间。通过此例,我们可以对过滤器有基本的理解,之后你将可以试着写出更复杂的过滤器应用。

//导入所需java类库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

//实现Filter接口
public class LogFilter implements Filter {
public void init(FilterConfig config)
throws ServletException{
//获取初始化参数
String testParam = config.getInitParameter("test-param");

//打印初化参数
System.out.println("Test Param: " + testParam);
}
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws java.io.IOException, ServletException {

//获得客户ip地址
String ipAddress = request.getRemoteAddr();

//输出客户ip和访问时间
System.out.println("IP "+ ipAddress + ", Time "
+ new Date().toString());

//将请求(或回复)传到过滤链的下一节
chain.doFilter(request,response);
}
public void destroy( ){
//在过滤器被移除服务之前由web容器调用
System.out.println(“the log filter is destroyed…”)
}
}

像编译普通java类一样编译LogFilter.java,然后将编译后的字节码文件LogFilter.class放入web应用的/WEB-INF/classes目录下。

在web.xml中配置过滤器

把定义好的过滤器映射到某个URL或JSP文件上,和在web.xml中配置servlet一样。在web.xml中创建如下的filter标签:

<filter>
<filter-name>LogFilter</filter-name>
<filter-class>LogFilter</filter-class>
<init-param>
<param-name>test-param</param-name>
<param-value>Initialization Paramter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


以上配置将应用到所有servlet和jsp,因为/*匹配所有文件。当然,你也可以将过滤器应用在某一个(些)servlet或jsp文件上。

现在访问任一servlet或jsp,你将会在web服务器日志中看到输出在控制台中的日志。你可以使用Log4j把日志保存在一个单独的文件中。


分别是:filter和filter-mapping。filter元素向系统注册一个过滤对象,filter-mapping元素指定该过滤对象所应用的URL。
1.filter元素
filter元素位于部署描述符文件(web.xml)的前部,所有filter-mapping、servlet或servlet-mapping元素之前。filter元素具有如下六个可能的子元素:
:icon 这是一个可选的元素,它声明IDE能够使用的一个图象文件。
:filter-name 这是一个必需的元素,它给过滤器分配一个选定的名字。
:display-name 这是一个可选的元素,它给出IDE使用的短名称。
:description 这也是一个可选的元素,它给出IDE的信息,提供文本文档。
:filter-class 这是一个必需的元素,它指定过滤器实现类的完全限定名。
:init-param 这是一个可选的元素,它定义可利用FilterConfig的getInitParameter方法读取的初始化参数。单个过滤器元素可包含多个init-param元素。

2.filter-mapping元素
filter-mapping元素位于web.xml文件中filter元素之后serlvet元素之前。它包含如下三个可能的子元素::
:filter-name 这个必需的元素必须与用filter元素声明时给予过滤器的名称相匹配。
:url-pattern 此元素声明一个以斜杠(/)开始的模式,它指定过滤器应用的URL。所有filter-mapping元素中必须提供url-pattern或 servlet-name。但不能对单个filter-mapping元素提供多个url-pattern元素项。如果希望过滤器适用于多个模式,可重复整个filter-mapping元素。
:servlet-name 此元素给出一个名称,此名称必须与利用servlet元素给予servlet或JSP页面的名称相匹配。不能给单个filter-mapping元素提供 多个servlet-name元素项。如果希望过滤器适合于多个servlet名,可重复这个filter-mapping元素。




使用多个过滤器

对于web应用,根据不同的目的,可以定义不同的过滤器。试想,你定义了两个过滤器:AuthenFilter(验证权限)和LogFilter(记录日志)。处理方式和上面类同,你需要像下面这样创建新的映射:

<filter>
<filter-name>LogFilter</filter-name>
<filter-class>LogFilter</filter-class>
<init-param>
<param-name>test-param</param-name>
<param-value>Initialization Paramter</param-value>
</init-param>
</filter>

<filter>
<filter-name>AuthenFilter</filter-name>
<filter-class>AuthenFilter</filter-class>
<init-param>
<param-name>test-param</param-name>
<param-value>Initialization Paramter</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
<filter-name>AuthenFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

过滤器执行顺序

filter-mapping元素在web.xml中的放置顺序决定了web容器应用各个过滤器的顺序。你可以颠倒filter-mapping元素次序来使过滤器反序执行。

例如,上面的例子会先应用LogFilter然后再应用AuthenFilter,而下面的例子执行顺序则相反:



<filter-mapping>      
 <filter-      name>AuthenFilter</filter-      name>      
 <      url-pattern>/*</      url-pattern>      
 </filter-mapping>      

 <filter-mapping>      
 <filter-      name>LogFilter</filter-      name>      
 <      url-pattern>/*</      url-pattern>      
 </filter-mapping>




建立一个过滤器涉及下列五个步骤:
1、建立一个实现Filter接口的类。这个类需要三个方法,分别是:doFilter、init和destroy。doFilter方法包含主要的过滤代码,init方法建立设置操作,而destroy方法进行清除。
2、 在doFilter方法中放入过滤行为。doFilter方法的第一个参数为ServletRequest对象。此对象给过滤器提供了对进入的信息(包括 表单数据、cookie和HTTP请求头)的完全访问。第二个参数为ServletResponse,通常在简单的过滤器中忽略此参数。最后一个参数为 FilterChain,如下一步所述,此参数用来调用servlet或JSP页。
3、调用FilterChain对象的doFilter方法。 Filter接口的doFilter方法取一个FilterChain对象作为它的一个参数。在调用此对象的doFilter方法时,激活下一个相关的过滤器。如果没有另一个过滤器与servlet或JSP页面关联,则servlet或JSP页面被激活。
4、对相应的servlet和JSP页面注册过滤器。在部署描述符文件(web.xml)中使用filter和filter-mapping元素。
5、禁用激活器servlet。防止用户利用缺省servlet URL绕过过滤器设置。




例子:

建立字符转换过滤器



1.新建-web-过滤器:SetCharacterEncodingFilter

会在web.xml中产生如下代码:



<filter> 
    
 <filter- 
    name>ChangeCodeFilter</filter- 
    name> 
    
 <display- 
    name>ChangeCodeFilter</display- 
    name> 
    
 <description></description> 
    
 <filter- 
    class>com.cnc.SetCharacterEncodingFilter</filter- 
    class> 
    
 </filter> 
    
 <filter-mapping> 
    
 <filter- 
    name>SetCharacterEncodingFilter</filter- 
    name> 
    
 < 
    url-pattern>/SetCharacterEncodingFilter</ 
    url-pattern> 
    
 </filter-mapping>




2.在过滤器的doFilter方法中添加如下代码:



public 
    void doFilter(ServletRequest arg0, ServletResponse arg1,FilterChain arg2) 
   throws IOException, ServletException { 
   
 arg0.setCharacterEncoding( 
   "UTF-8"); 
    //设定字体编码为UTF-8 
   
 arg2.doFilter(arg0, arg1); 
   // 传递控制到下一个过滤器 
   
 }


3.在web.xml中进行部署



在web.xml的过滤器-编辑器中选择:servlet 映射 - 添加 - Faces Servlet
会在web.xml中产生如下代码:



<filter-mapping> 
   
 <filter- 
   name>SetCharacterEncodingFilter</filter- 
   name> 
   
 <servlet- 
   name>Faces Servlet</servlet- 
   name> 
   
 </filter-mapping>