`
glacier3
  • 浏览: 384889 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

使用 Java Servlets 2.4 来执行过滤

阅读更多
Servlet API 很久以前就已成为企业应用开发的基石,而 Servlet 过滤器则是对 J2EE 家族的相对较新的补充。在 J2EE探索者系列文章的最后一篇中,作者 Kyle Gabhart 将向您介绍 Servlet 过滤器体系结构,定义过滤器的许多应用,并指导您完成典型过滤器实现的三个步骤。他还会透露bean 的一些激动人心的变化,预计刚发布的 Java Servlet 2.4 规范会引入这些变化。

Servlet 过滤器是可插入的 Web 组件,它允许我们实现 Web 应用程序中的预处理和后期处理逻辑。过滤器支持 servlet 和 JSP 页面的基本请求处理功能,比如日志记录、性能、安全、会话处理、XSLT 转换,等等。 过滤器最初是随 Java Servlet 2.3 规范发布的,最近定稿的 2.4 规范对它进行了重大升级。在这 J2EE 探索者系列文章的最后一篇中,我将向您介绍 Servlet 过滤器的基础知识 ―― 比如总体的体系结构设计、实现细节,以及在 J2EE Web 应用程序中的典型应用,还会涉及一些预计最新的 Servlet 规范将会提供的扩展功能。

Servlet 过滤器是什么?

Servlet 过滤器是小型的 Web 组件,它们拦截请求和响应,以便查看、提取或以某种方式操作正在客户机和服务器之间交换的数据。过滤器是通常封装了一些功能的 Web 组件,这些功能虽然很重要,但是对于处理客户机请求或发送响应来说不是决定性的。典型的例子包括记录关于请求和响应的数据、处理安全协议、管理会话属性,等等。过滤器提供一种面向对象的模块化机制,用以将公共任务封装到可插入的组件中,这些组件通过一个配置文件来声明,并动态地处理。

Servlet 过滤器中结合了许多元素,从而使得过滤器成为独特、强大和模块化的 Web 组件。也就是说,Servlet 过滤器是:

  • 声明式的:过滤器通过 Web 部署描述符(web.xml)中的 XML 标签来声明。这样允许添加和删除过滤器,而无需改动任何应用程序代码或 JSP 页面。
  • 动态的:过滤器在运行时由 Servlet 容器调用来拦截和处理请求和响应。
  • 灵活的:过滤器在 Web 处理环境中的应用很广泛,涵盖诸如日志记录和安全等许多最公共的辅助任务。过滤器还是灵活的,因为它们可用于对来自客户机的直接调用执行预处理和后期处理,以及处理在防火墙之后的 Web 组件之间调度的请求。最后,可以将过滤器链接起来以提供必需的功能。
  • 模块化的:通过把应用程序处理逻辑封装到单个类文件中,过滤器从而定义了可容易地从请求/响应链中添加或删除的模块化单元。
  • 可移植的:与 Java 平台的其他许多方面一样,Servlet 过滤器是跨平台和跨容器可移植的,从而进一步支持了 Servler 过滤器的模块化和可重用本质。
  • 可重用的:归功于过滤器实现类的模块化设计,以及声明式的过滤器配置方式,过滤器可以容易地跨越不同的项目和应用程序使用。
  • 透明的:在请求/响应链中包括过滤器,这种设计是为了补充(而不是以任何方式替代)servlet 或 JSP 页面提供的核心处理。因而,过滤器可以根据需要添加或删除,而不会破坏 servlet 或 JSP 页面。

所以 Servlet 过滤器是通过一个配置文件来灵活声明的模块化可重用组件。过滤器动态地处理传入的请求和传出的响应,并且无需修改应用程序代码就可以透明地添加或删除它们。最后,过滤器独立于任何平台或者 Servlet 容器,从而允许将它们容易地部署到任何相容的 J2EE 环境中。

在接下来的几小节中,我们将进一步考察 Servlet 过滤器机制的总体设计,以及实现、配置和部署过滤器所涉及的步骤。我们还将探讨 Servlet 过滤器的一些实际应用,最后简要考察一下模型-视图-控制器(MVC)体系结构中包含的 Servlet 过滤器,从而结束本文的讨论。





回页首


Servlet 过滤器体系结构

正如其名称所暗示的, Servlet 过滤器用于拦截传入的请求和/或传出的响应,并监视、修改或以某种方式处理正在通过的数据流。过滤器是自包含、模块化的组件,可以将它们添加到请求/响应链中,或者在无需影响应用程序中其他 Web 组件的情况下删除它们。过滤器仅只是改动请求和响应的运行时处理,因而不应该将它们直接嵌入 Web 应用程序框架,除非是通过 Servlet API 中良好定义的标准接口来实现。

Web 资源可以配置为没有过滤器与之关联(这是默认情况)、与单个过滤器关联(这是典型情况),甚至是与一个过滤器链相关联。那么过滤器究竟做什么呢? 像 servlet 一样,它接受请求并响应对象。然后过滤器会检查请求对象,并决定将该请求转发给链中的下一个组件,或者中止该请求并直接向客户机发回一个响应。如果请求被转发了,它将被传递给链中的下一个资源(另一个过滤器、servlet 或 JSP 页面)。在这个请求设法通过过滤器链并被服务器处理之后,一个响应将以相反的顺序通过该链发送回去。这样就给每个过滤器都提供了根据需要处理响应对象的机会。

当过滤器在 Servlet 2.3 规范中首次引入时,它们只能过滤 Web 客户机和客户机所访问的指定 Web 资源之间的内容。如果该资源然后将请求调度给其他 Web 资源,那就不能向幕后委托的任何请求应用过滤器。2.4 规范消除了这个限制。Servlet 过滤器现在可以应用于 J2EE Web 环境中存在请求和响应对象的任何地方。因此,Servlet 过滤器可以应用在客户机和 servlet 之间、servlet 和 servlet 或 JSP 页面之间,以及所包括的每个 JSP 页面之间。这才是我所称的强大能力和灵活性!





回页首


实现一个 Servlet 过滤器

他们说“好事多磨”。我不知道“他们”指的是谁,或者这句古老的谚语究竟有多真实,但是实现一个 Servlet 过滤器的确要经历三个步骤。首先要编写过滤器实现类的程序,然后要把该过滤器添加到 Web 应用程序中(通过在 Web 部署描述符 /web.xml 中声明它),最后要把过滤器与应用程序一起打包并部署它。我们将详细研究这其中的每个步骤。

1. 编写实现类的程序

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

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

  • init() :这个方法在容器实例化过滤器时被调用,它主要设计用于使过滤器为处理做准备。该方法接受一个 FilterConfig 类型的对象作为输入。
  • doFilter() :与 servlet 拥有一个 service() 方法(这个方法又调用 doPost() 或者 doGet() )来处理请求一样,过滤器拥有单个用于处理请求和响应的方法―― doFilter() 。这个方法接受三个输入参数:一个 ServletRequestresponse 和一个 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());
     }
}

这个过滤器的生命周期很简单,不管怎样,我们还是研究一下它吧:

初始化
当容器第一次加载该过滤器时, init() 方法将被调用。该类在这个方法中包含了一个指向 FilterConfig 对象的引用。我们的过滤器实际上并不需要这样做,因为其中没有使用初始化信息,这里只是出于演示的目的。
过滤
过滤器的大多数时间都消耗在这里。 doFilter() 方法被容器调用,同时传入分别指向这个请求/响应链中的 ServletRequestServletResponseFilterChain 对象的引用。然后过滤器就有机会处理请求,将处理任务传递给链中的下一个资源(通过调用 FilterChain 对象引用上的 doFilter() 方法),之后在处理控制权返回该过滤器时处理响应。
析构
容器紧跟在垃圾收集之前调用 destroy() 方法,以便能够执行任何必需的清理代码。

2. 配置 Servlet 过滤器

过滤器通过 web.xml 文件中的两个 XML 标签来声明。 <filter> 标签定义过滤器的名称,并且声明实现类和 init() 参数。 <filter-mapping> 标签将过滤器与 servlet 或 URL 模式相关联。

清单 2 摘自一个 web.xml 文件,它展示了如何声明过滤器的包含关系:



清单 2. 在 web.xml 中声明一个过滤器
<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 容器将处理之后的其他所有事情。





回页首


过滤器的许多应用

您在 J2EE Web 应用程序中利用过滤器的能力,仅受到您自己的创造性和应用程序设计本领的限制。在适合使用装饰过滤器模式或者拦截器模式的任何地方,您都可以使用过滤器。过滤器的一些最普遍的应用如下:

  • 加载:对于到达系统的所有请求,过滤器收集诸如浏览器类型、一天中的时间、转发 URL 等相关信息,并对它们进行日志记录。
  • 性能:过滤器在内容通过线路传来并在到达 servlet 和 JSP 页面之前解压缩该内容,然后再取得响应内容,并在将响应内容发送到客户机机器之前将它转换为压缩格式。
  • 安全:过滤器处理身份验证令牌的管理,并适当地限制安全资源的访问,提示用户进行身份验证和/或将他们指引到第三方进行身份验证。过滤器甚至能够管理访问控制列表(Access Control List,ACL),以便除了身份验证之外还提供授权机制。将安全逻辑放在过滤器中,而不是放在 servlet 或者 JSP 页面中,这样提供了巨大的灵活性。在开发期间,过滤器可以关闭(在 web.xml 文件中注释掉)。在生产应用中,过滤器又可以再次启用。此外还可以添加多个过滤器,以便根据需要提高安全、加密和不可拒绝的服务的等级。
  • 会话处理:将 servlet 和 JSP 页面与会话处理代码混杂在一起可能会带来相当大的麻烦。使用过滤器来管理会话可以让 Web 页面集中精力考虑内容显示和委托处理,而不必担心会话管理的细节。
  • XSLT 转换:不管是使用移动客户端还是使用基于 XML 的 Web 服务,无需把逻辑嵌入应用程序就在 XML 语法之间执行转换的能力都绝对是无价的。




回页首


使过滤器适应 MVC 体系结构

模型-视图-控制器(Model-View-Controller,MVC)体系结构是一个有效的设计,它现在已作为最重要的设计方法学,整合到了诸如 Jakarta Struts 和 Turbine 等大多数流行的 Web 应用框架中。过滤器旨在扩充 MVC 体系结构的请求/响应处理流。不管请求/响应发生在客户机和服务器之间,还是发生在服务器上的其他组件之间,过滤器在处理流中的应用都是相同的。从 MVC 的观点看,调度器组件(它或者包括在控制器组件中,或者配合控制器组件工作)把请求转发给适当的应用程序组件以进行处理。这使得控制器层成为包括 Servlet 过滤器的最佳位置。通过把过滤器放在控制器组件本身的前面,过滤器可以应用于所有请求,或者通过将它放在控制器/调度器与模型和控制器之间,它可以应用于单独的 Web 组件。

MVC 体系结构广为传播,并具有良好的文档。请通过 参考资料中的链接了解关于 MVC 和 MVC 体系结构中的 Servlet 实现的更多信息。





回页首


结束语

虽然过滤器才出现几年时间,但它们本身已作为一个关键组件嵌入到了所有敏捷的、面向对象的 J2EE Web 应用程序中。本文向您介绍了 Servlet 过滤器的使用。 本文讨论了过滤器的高级设计,比较了当前规范(2.4)和以前(2.3)的模型,讲述了实现过滤器所涉及的精确步骤,以及如何在 Web 应用程序中声明过滤器,然后与应用程序一起部署它。本文还阐述了 Servlet 过滤器的一些最普遍应用,并提到了过滤器如何适应传统的 MVC 体系结构。

这是 J2EE 探索者系列的最后一篇文章。我们在年初通过粗略研究 Enterprise JavaBean 组件来开始我们的旅程,并提到了何时使用这些组件才真正有意义,以及何时这些组件才会变得大材小用的问题。然后我们将目光转向了 Web 层,绘制了一条通过 Servlet、JSP 页面、JavaBean 技术以及 Java Servlet API 中的无数选择和功能的路径。在这个系列文章中与您一起艰苦跋涉真是一件快乐的事情。我享受着编写这个系列文章的乐趣,并且我从大家的反馈中知道,这对您也是一个很有价值的过程。感谢您对本系列文章的参与。祝您好运,探索快乐!

分享到:
评论

相关推荐

    Professional Servlets and JSP The J2EE Web Tier

    本书《Professional Servlets and JSP The J2EE Web Tier》是Jayson Falkner和Kevin Jones所著,是关于如何使用JavaServer Pages 2.0和Servlets 2.4构建动态Java Web应用的详尽指南。它提供了使用Servlet和JSP技术...

    Java EE 6 标准与规范(中文版)

    示例展示了如何使用Java EE 6的安全性框架来保护Web应用程序的特定部分。 **2.3 安全体系结构** - **身份验证**:使用JAAS(Java Authentication and Authorization Service)进行身份验证。 - **授权**:通过Web....

    J2EE JAR包(J2EE1.3 J2EE1.4 J2EE5.0 )

    它为开发者提供了多种服务和组件模型,包括Java Servlets、JavaServer Pages (JSP)、JavaBeans、EJB(Enterprise JavaBeans)、JMS(Java Message Service)、JTA(Java Transaction API)等,以支持Web应用的开发和...

    tomcat5.5安装版

    Apache Tomcat 5.5 是一个广泛使用的开源Java Servlet容器,特别用于运行JavaServer Pages (JSP) 和Java Servlets。这个"tomcat5.5安装版"包含了所有必要的组件来搭建一个完整的Tomcat服务器环境。以下是关于Tomcat ...

    apache-tomcat-5.5.17.rar

    Apache Tomcat作为Servlet容器,其主要任务是解释和执行Java Servlets,这些Servlet是用Java语言编写的服务器端组件,可以处理HTTP请求并返回响应。同时,Tomcat也支持JSP,这是一种基于Java的动态网页技术,允许...

    tomcat5.50

    1. 支持Servlet 2.4和JSP 2.0规范:这两个版本的规范带来了更好的性能和更丰富的功能,如过滤器链的改进,以及JSP标签库的增强。 2. JMX(Java Management Extensions)改进:增强了对服务器状态监控和管理的能力,...

    j2ee Api v1.4 英文版

    5. **Java Persistence API (JPA)**: 虽然JPA 1.0在J2EE 5中才成为标准,但在J2EE 1.4中,开发者可以使用Hibernate等第三方库来实现对象关系映射(ORM)。 6. **Java Transaction API (JTA)**: JTA定义了跨系统事务...

    J2ee1.4sdk tutorial

    1. **Servlet 2.4 规范**:增强了会话管理、过滤器和监听器等功能。 2. **JSP 2.0**:引入了EL(Expression Language),使得在JSP中访问JavaBean属性更加简单。 3. **JSF 1.1**:首次引入到J2EE规范,提供了MVC...

    中间件tomcat5.5

    Tomcat5.5是Tomcat的一个重要版本,发布于2006年,为开发者提供了运行Java Servlets和JSP(JavaServer Pages)的平台。 ### 一、Tomcat5.5概述 1. **版本历史**:Tomcat5.5是在Tomcat5系列中的主要版本,它基于...

    Tomcat-5.0.19

    1. **Servlet 2.4支持**:这个版本的Tomcat实现了Servlet 2.4规范,提供了更强大的服务器端编程能力,包括对过滤器和监听器的增强支持,以及更灵活的错误处理机制。 2. **JSP 2.0支持**:同时,它还支持JSP 2.0,...

    web-app_2_4.xsd

    总的来说,`web-app_2_4.xsd`是理解Java Web应用程序部署和配置的关键,它定义了Servlet 2.4规范下的Web应用结构,并提供了验证部署描述符的工具。虽然现代Web开发可能已经不再依赖这种XML配置方式,但对于历史项目...

    学习J2EE 1_4同学可以下载看看会对你学习J2EE有帮助的!!!

    在J2EE 1_4中,Servlet 2.4规范引入了过滤器(Filters)和监听器(Listeners),增强了对请求处理的控制和应用状态管理。 #### 2.2 JavaServer Pages (JSP) JSP是一种用于创建动态网页的技术,它允许开发者将HTML...

    BES 8.0 Development Guide

    3. **Java EE API**:了解 Java EE 核心组件,如 Servlets、JSP、EJB 等。 4. **XML**:能够读写 XML 文件,理解 XML 命名空间、DTD 和 Schema。 5. **BES 管理控制台、iastool 命令行管理工具、BES Eclipse Plugin ...

    Tomcatweb配置参照.pdf

    在Java Web开发中,Tomcat是一款广泛应用的开源Servlet容器,它负责解析和执行Java Servlets以及处理JSP页面。Tomcat的配置主要通过`web.xml`文件进行,这个文件是Web应用的部署描述符,定义了应用的行为和配置信息...

    web.xml文件详解

    总的来说,web.xml文件是Java Web应用配置的核心,通过它,开发者可以精细控制应用的运行行为,实现各种功能,如URL映射、过滤器链、安全性设置等。理解并熟练掌握web.xml文件的配置,对于开发和维护高质量的Java ...

    Struts2 入门培训

    Struts2可以运行在任何支持Java Servlets和Java EE的服务器上,如Tomcat、Jetty等。开发环境通常需要JDK 1.5或以上版本,以及相应的构建工具,如Maven或Ant。 **1.2. 包依赖** Struts2框架需要一系列的依赖库,包括...

    JSP2.0技术手册Code

    3. **CH18**: 可能涉及JSP 2.0引入的Servlet 2.4规范,包括对请求处理的改进、过滤器和监听器的使用,以及MVC模式的应用。这个章节的代码可能演示了如何利用这些新功能来增强应用的可维护性和性能。 4. **error....

    J2EE 基础教程ppt

    - **Servlet 2.4规范**:增强了过滤器和监听器功能,引入了表达式语言EL。 - **JSTL 1.1**:JavaServer Pages Standard Tag Library提供了更丰富的标签库。 - **JPA**:引入了ORM(对象关系映射)框架,简化了与...

    J2EE前端应用程式架构与

    【J2EE前端的相关规格和技术】包括JSP(JavaServer Pages)、Servlets,它们是构建J2EE前端的基础。JSP 2.0/2.4和Servlet 2.4/3.x是常见的版本。JSP Custom Tag Library和JSTL(JSP标准标签库)提供了更多的功能,...

Global site tag (gtag.js) - Google Analytics