servlet2.3规范之六——过滤

6 过滤

filter(过滤器)是Java servlet 2.3API的新增特性。filter允许请求资源和资源的响应的载荷和header信息可以快速转换。

 

本章描述了这些新的servlet API类和方法,它们提供了一个轻量级框架来过滤激活的静态内容。描述了在web应用中如何配置filter,以及实现的约定和语义。

 

Servlet filterAPI文档参见本文的API定义章节。filter的配置语法由第13章的DTDdocument type definition)指定。读者在阅读本章时应该参考这些资源。

 

6.1 filter是什么?

filter是一段可重用的代码,可以转换HTTP请求,响应的内容和header信息。filter通常不会象servlet那样创建一个response或者对请求作出响应,而只是修改对资源的请求或来自资源的响应。

 

filter可以对动态或者静态内容起作用。对本章而言,动态和静态内容统称为web资源。

 

在下列函数类型之中,filter编写人员可利用的有

 

在请求函数调用之前访问资源。

在函数调用之前对资源请求的处理。

通过包装自定义的request对象中的请求对请求header和数据的修改。

通过提供自定义的response对象对response headerresponse数据的修改。

在函数调用之后拦截资源的调用。

• 0个,1个或多个filter以指定顺序对一个servlet,一组servlet或静态内容的动作。

 

6.1.1 过滤组件示例

认证filter

日志与审核filter

图片转换filter

数据压缩filter

加密filter

令牌filter

触发资源访问事件的filter

转换XML内容的XSL/T filter

• MIME类型链filter

缓存filter

 

6.2 主要概念

本节主要描述过滤模型概念。

 

应用开发人员通过实现javax.servlet.Filter接口,并提供一个无参的公共构造函数来创建filter。该类和组成web应用的静态内容和servlet一起打包成WAR文件。部署描述符中使用filter元素声明filterfilter或者filter集合可以在部署描述符中定义filter-mapping元素来进行配置。通过servlet的逻辑名称filter映射到一个特定servlet,或者通过映射一个URL patterfilter来映射到一组servlet和静态内容资源

 

6.2.1 filter生命周期

web应用发布之后,请求引起容器访问web资源之前,容器必须定位下面所说的web资源中应用到的filter列表。容器必须确保已经实例化了列表中的每个filter并调用它的init(FilterConfig config)方法。如不能正确执行,filter可以抛出异常。如果异常类型为UnavailableException,容器可以检查异常的isPermanent属性,并且可能选择在以后某个时间重试filter

 

容器的每个虚拟机只为配置描述文件中的每个filter的声明实例化一个实例。容器提供filter config作为filter配置描述符的声明,web应用的ServletContext引用,以及一组初始化参数。

 

当容器接收到请求时,将取得列表中的第一个filter实例,并调用它的doFilter方法,传入ServletRequestServletResponse和将使用的FilterChain对象的引用。

 

filter doFilter方法的实现通常遵循以下范式或者其中的一部分

 

1步:方法检查请求的header

 

2步:它可以使用ServletRequest或者HttpServletRequest自定义实现来包装request对象,以便修改请求header或数据。

 

3步:它可以使用ServletResponse或者HttpServletResponse自定义实现来包装传入doFilter方法的response对象,以便修改响应header或数据。

 

4: filter可以调用filter链中的下一个实体。下一个实体可能是另一个filter,或者如果发起调用的filter是部署描述符中配置的链的最后一个filter,下一个实体则是目标web资源。下一个实体的调用受调用FilterChain对象的doFilter方法,传入的请求和响应,或者可能已创建好的包装版本的影响。

 

由容器提供的filter链的doFilter方法的实现,必须定位到filter链中的下一个实体,并调用它的doFilter方法,传递合适的requestresponse对象。

 

filter链可以通过不调用下一个实体,让filter负责填充response对象以阻塞请求。

 

5步:在链中的下一个filter调用之后,filter可能检查响应header

 

6步:filter可能已经抛出了一个异常,表示处理中有错误。如果filterdoFilter处理中抛出UnavailableException异常,容器不可以试图继续沿着filter链处理。如果异常没有标记为永久,它可以选择稍后重试整个链。

 

当链中的最后一个filter调用后,下一个访问的实体为链末端的目标servlet或资源。

 

filter实例可以从容器服务中删除之前,容器必须先调用filterdestroy方法,以使filter能够释放任何资源,并执行其他清除操作。

 

6.2.2 包装请求和响应

过滤的核心概念是包装requestresponse,以便能重载行为以执行过滤任务。在这种模式中,开发人员不仅能够重载requestresponse对象已有的方法,还可以为针对链上的某个filter或目标web资源特定的过滤任务提供新的API。比如,开发人员可能想使用更高级的输出对象(输出流和writer)来扩展response对象,比如允许DOM对象写回客户端的API

 

要支持这种形式的filter,容器必须支持以下需求。当一个filter调用容器的filter链实现的doFilter方法时,容器必须确保它传递给filter链的下一个实体的requestresponse对象(如果它是链中的最后一个filter,传递给目标web资源)和调用filter传递给doFilter方法的对象相同。

 

当开发人员将包装好的requestresponse对象传递给requestDispatcher时也有同样需求;传递给servlet调用的requestresponse对象必须与此相同。

 

6.2.3 filter环境

使用部署描述符的init-params元素,可以将一组初始化参数和filter关联。这些参数的名称和值filter运行时可通过filterFilterConfig对象的getInitParameter或者getInitParameterNames方法使用。并且,FilterConfig提供对web应用ServletContext的访问,比如加载资源,日志功能,以及ServletContext属性列表中状态的存储。

 

6.2.4 Web应用中filter的配置

部署描述符中使用filter元素定义filter。在这元素中,程序员声明

 

filter-name:用来将filter映射到servlet或者URL

filter-class:容器用来识别filter类型

init-paramsfilter的初始化参数

 

指定工具实现的图标,文本描述和显示名称是可选的。容器必须为部署描述符中每一个filter声明实例化一个定义filterJava类实例。因此,如果开发人员用相同的filter类进行两次filter声明,那么容器将对同样的filter类实例化两个。

这里是一个filter声明的示例:

 

<filter>

<filter-name>Image Filter</filter-name>

<filter-class>com.acme.ImageServlet</filter-class>

</filter>

 

一旦filter在部署描述符中声明,集成人员使用filter-mapping元素定义web应用中要应用filterservlet和静态资源。filter可以使用servlet-name元素关联到一个servlet。比如,下列将Image Filter filter映射到ImageServlet servlet

 

<filter-mapping>

<filter-name>Image Filter</filter-name>

<servlet-name>ImageServlet</servlet-name>

</filter-mapping>

 

使用url-pattern形式的filter映射,filter可以和一组servlet和静态内容关联:

 

<filter-mapping>

<filter-name>Logging Filter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

 

这是一个应用到web应用所有servlet和静态内容页面的Logging Filter,因为每一个请求URI都匹配“/* URL模式。

 

当使用url-pattern形式的filter-mapping元素时,容器必须确定url-pattern是否匹配使用第11章中定义的路径映射规则的请求URI

 

在构建filter链中容器对于特定请求URI应用的顺序是

 

1. url-pattern匹配的filter映射遵从部署描述符中这些元素出现的顺序

2. servlet-name匹配的filter映射遵从部署描述符中这些元素出现的顺序

 

这需求意味着容器在接收传入的请求时:

 

根据11.2节的规则识别目标web资源。

如果存在以servlet名称匹配的filter,并且web资源含servlet-name,那么容器将按照配置描述符中声明的顺序构建filter链。链中最后一个filter是最后一个servlet-name匹配filter,将由它来调用目标web资源。

如果存在使用url-pattern匹配的filter,并且url-pattern根据11.2节的规则匹配请求URI,那么容器将按照配置描述符中声明的顺序构建url-pattern匹配的filter链。链中的最后一个filter,是调用url-pattern匹配链中第一个filter,如果没有的话调用目标资源的或者是并且该filter将调用第一个servlet-name匹配的filter,如没有则直接调用目的web资源的filter

 

若想提高性能, 容器最好缓存filter链,以免每次请求都要重新计算。

 

你可能感兴趣的:(Web,servlet,api,filter,header,logging)