首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

使用 Java Servlets 2.4 来执行过滤(2)

使用 Java Servlets 2.4 来执行过滤(2)

实现一个 Servlet 过滤器他们说“好事多磨”。我不知道“他们”指的是谁,或者这句古老的谚语究竟有多真实,但是实现一个Servlet 过滤器的确要经历三个步骤。首先要编写过滤器实现类的程序,然后要把该过滤器添加到 Web 应用程序中(通过在 Web 部署描述符/web.xml 中声明它),最后要把过滤器与应用程序一起打包并部署它。我们将详细研究这其中的每个步骤。
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. 一个过滤器类实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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());
     }
}




这个过滤器的生命周期很简单,不管怎样,我们还是研究一下它吧:
初始化
当容器第一次加载该过滤器时,       init() 方法将被调用。该类在这个方法中包含了一个指向       FilterConfig 对象的引用。我们的过滤器实际上并不需要这样做,因为其中没有使用初始化信息,这里只是出于演示的目的。      
过滤
过滤器的大多数时间都消耗在这里。       doFilter() 方法被容器调用,同时传入分别指向这个请求/响应链中的       ServletRequest 、       ServletResponse 和       FilterChain 对象的引用。然后过滤器就有机会处理请求,将处理任务传递给链中的下一个资源(通过调用       FilterChain  对象引用上的       doFilter() 方法),之后在处理控制权返回该过滤器时处理响应。      
析构
容器紧跟在垃圾收集之前调用       destroy() 方法,以便能够执行任何必需的清理代码。      
2. 配置 Servlet 过滤器过滤器通过 web.xml 文件中的两个 XML 标签来声明。         <filter> 标签定义过滤器的名称,并且声明实现类和         init() 参数。         <filter-mapping> 标签将过滤器与 servlet 或 URL 模式相关联。      
清单 2 摘自一个 web.xml 文件,它展示了如何声明过滤器的包含关系:
清单 2. 在 web.xml 中声明一个过滤器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<filter>
     <filter-name>Page Request Timer</filter-name>
     <filter-class>TimeTrackFilter</filter-class>
</filter>
<filter-mapping>
     <filter-name>Page Request Timer</filter-name>
     <servlet-name>Main Servlet</servlet-name>
</filter-mapping>
<servlet>
     <servlet-name>Main Servlet</servlet-name>
     <servlet-class>MainServlet</servlet-class>
</servlet>
<servlet-mapping>
     <servlet-name>Main Servlet</servlet-name>
     <url-pattern>/*</url-pattern>
</servlet-mapping>




上面的代码示例声明了一个过滤器("Page Request Timer"),并把它映射到一个 servlet("Main Servlet")。然后为该 servlet 定义了一个映射,以便把每个请求(由通配符指定)都发送到该 servlet。这是控制器组件的典型映射声明。您应该注意这些声明的顺序,因为千万不能背离这些元素的顺序。
3. 部署 Servlet 过滤器事实上,与 Web 应用程序一起部署过滤器绝对不涉及任何复杂性。只需把过滤器类和其他 Web 组件类包括在一起,并像您通常所做的那样把 web.xml 文件(连同过滤器定义和过滤器映射声明)放进 Web 应用程序结构中,servlet 容器将处理之后的其他所有事情。
返回列表