实现一个 Servlet 过滤器

1. 编写实现类的程序

过滤器 API 包含 3 个简单的接口(又是数字 3!),它们整洁地嵌套在 javax.servlet 包中。那 3 个接口分别是 Filter 、 FilterChain 和 FilterConfig 。从编程的角度看,过滤器类将实现 Filter 接口,然后使用这个过滤器类中的 FilterChain 和 FilterConfig 接口。该过滤器类的一个引用将传递给 FilterChain 对象,以允许过滤器把控制权传递给链中的下一个资源。 FilterConfig 对象将由容器提供给过滤器,以允许访问该过滤器的初始化数据。

为了与我们的三步模式保持一致,过滤器必须运用三个方法,以便完全实现 Filter 接口:

init() :这个方法在容器实例化过滤器时被调用,它主要设计用于使过滤器为处理做准备。该方法接受一个 FilterConfig 类型的对象作为输入。

doFilter() :与 servlet 拥有一个 service() 方法(这个方法又调用 doPost() 或者 doGet() )来处理请求一样,过滤器拥有单个用于处理请求和响应的方法―― doFilter() 。这个方法接受三个输入参数:一个 ServletRequest 、 response 和一个 FilterChain 对象。

destroy() :正如您想像的那样,这个方法执行任何清理操作,这些操作可能需要在自动垃圾收集之前进行。
清单 1 展示了一个非常简单的过滤器,它跟踪满足一个客户机的 Web 请求所花的大致时间。


清单 1. 一个过滤器类实现


import javax.servlet.*;
import java.util.*;
import java.io.*;

public class TimeTrackFilter implements Filter {
     private FilterConfig filterConfig = null;

     public void init(FilterConfig filterConfig)
        throws ServletException {

        this.filterConfig = filterConfig;
     }

     public void destroy() {

        this.filterConfig = null;
     }

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

        Date startTime, endTime;
        double totalTime;

        startTime = new Date();

        // Forward the request to the next resource in the chain
        chain.doFilter(request, wrapper);

        // -- Process the response -- \\

        // Calculate the difference between the start time and end time
        endTime = new Date();
        totalTime = endTime.getTime() - startTime.getTime();
        totalTime = totalTime / 1000; //Convert from milliseconds to seconds

        StringWriter sw = new StringWriter();
        PrintWriter writer = new PrintWriter(sw);

        writer.println();
        writer.println("===============");
        writer.println("Total elapsed time is: " + totalTime + " seconds." );
        writer.println("===============");

        // Log the resulting string
        writer.flush();
        filterConfig.getServletContext().
           log(sw.getBuffer().toString());

     }
}