过滤器仅只是改动请求和响应的运行时处理,因而不应该将它们直接嵌入 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 中声明它),
最后要把过滤器与应用程序一起打包并部署它。我们将详细研究这其中的每个步骤。
编写实现类的程序
过滤器 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 import javax.servlet.*;
2 import java.util.*;