文档章节

Servlet Specification V2.4——SRV.6 Filtering

悟空太多啦
 悟空太多啦
发布于 2015/12/21 00:02
字数 2838
阅读 53
收藏 1

SRV.6 Filtering

 

Filters are Java components that allow on the fly transformations of payload and header information in both the request into a resource and the response from a resource.
        这一节描述了Java Servlet v2.4 API中的一部分classes和methods,它们为filter静态和动态的内容提供了一个轻量级的框架。这一节也描述了如何在web应用中配置filters,filter的使用惯例以及它们的实现的语法。
        SRV.14提供了servlet filters的API文档。Filter的配置语法由部署描述符给出,这会在SRV13 “Deployment Descriptor” 中描述。在阅读本章时,读者应该把这些资源作为参考。

 

 

SRV.6.1 What is a filter?

        Filter是一种可反复使用的的代码,它可以传送HTTP request、response的内容,以及header信息。Filters不创建response或者是向servlets那样响应request,但它们可以为request修改或适配资源,还可以为response修改或适配资源。
        Filters可以作用于动态或静态内容。作为本章节来说,提到的动态和静态内容指的是web资源。

  • 对使用filter的开发者来说,下面是filter一些有用的特性:

  • 可以在Request调用资源前访问资源。

  • 可以在对资源的Request执行前被调用。

  • 可以针对包装过的自定义版本request的request header及data进行修改。

  • 可以针对包装过的自定义版本response的response header及data进行修改。

  • 在资源被调用后拦截资源(The interception of an invocation of a resource after its call)。

  • 以特定的顺序,将零个、一个、或多个filter作用于一个servlet,一组servlet,或者静态内容。

 

SRV.6.1.1 Examples of Filtering Components

  • Authentication filters

  • Logging and auditing filters

  • Image conversion filters

  • Data compression filters

  • Encryption filters

  • Tokenizing filters

  • Filters that trigger resource access events

  • XSL/T filters that transform XML content

  • MIME-type chain filters

  • Caching filters

 

 

SRV.6.2 Main Concepts

Filter模型的主要概念都将在本节讨论。
        应用程序开发者可以通过实现javax.servlet.Filter接口来创建一个filter,并且要提供一个公共的无参构造方法。Filter的class文件与其他组成web应用程序的静态内容和其他servlet的class一起打包到Web Archive(war)中。在部署描述符中,filter通过<filter>元素来声明,filter或filters集合可以通过定义<filter-mapping>元素被调用。调用通过把filter映射到一个特定的servlet(通过servlet的逻辑名称)来实现。或者通过URL pattern把filter映射到到一组servlet或者静态内容资源上。

 

SRV.6.2.1 Filter Lifecycle

在部署了web application之后,request致使container去访问web资源之前,container必须设置好filter列表,这些filter必须像下面描述的那样作用于web resources。container必须保证自身已经把filter列表每一个filter按照恰当的class实例化filter,并且调用它的init(FilterConfig config)方法。filter会通过抛出异常来表明它没有正确地运行。如果异常的类型是UnavaliableException,container可以检查exception的isPermanent属性,并且可以选择在下面的某个时间重新尝试实例化。
        部署描述符中声明的filter,在container的每一个JVM中,一个<filter>标签只对应一个实例。Container来提供声明在filter的部署描述符中的filter配置,web application的ServletContext的引用,以及初始化参数集合。
当container接收到request时,container从filter列表中取出第一个filter实例,调用filter的doFilter方法,将参数ServletRequest,ServletResponse和container使用的FilterChain对象的引用传递进去。
        典型的情况下,filter的doFilter方法会被实现以下全部或部分功能模式:

  1. 检查request的headers

  2. 为了修改request headers或者data,doFilter方法可以把传入的request对象用ServletRequest或HttpServletRequest接口的自定义实现包装request对象。

  3. 为了修改request headers或者data,doFilter方法可以用ServletResponse或HttpServletResponse接口的自定义实现包装request对象。

  4. Filter可以调用filter chain中的下一个实体。下一个实体可以是另一个filter,或者如果filter做的调用是部署描述符中配置的最后一个filter,那下一个实体就是目标web resource。下一个实体的调用通过调用filter chain对象上的doFilter方法完成,并且把request和response传递进去。
    Filter chain实现的doFilter方法,通过container提供,必须找出在filter chain中的下一个实体并且调用它的doFilter方法,传进恰当的request和response对象。
    非此即彼的,filter chain可以通过不对下一个实体进行调用的方式阻塞request,把填写response对象的责任留给自己。

  5. 在对filter chain中下一个filter的调用之后,filter可以检验response headers。

  6. 二选一的,filter有可能在执行过程中抛出一个异常来指示一个错误。如果filter在执行doFilter的过程中抛出了UnavailableException,那么container一定不会试图继续执行下面的filter chain。如果exception没有标记为永久的话,它会在接下来的某个时间重新尝试整个chain。

  7. 当filter chain中最后一个filter被调用时,下一个要被存取的实体就是目标servlet或者在chain中最后面的资源。

  8. 在filter实例从container的服务中被移除之前,container必须首先调用filter上的destroy方法来使filter释放掉所有的资源并且执行其他清理操作

 

SRV.6.2.2 Wrapping Requests and Responses

        过滤的核心理念是为了包装request或是response以便可以override行为来执行过滤任务。在这个模型中,开发者不仅有能力在request,response对象上override已有的方法,也可以给某个filter或接下来的filter chain中的目标web资源提供适合某个特定过滤任务的新的API。例如,开发者想用高级output对象继承response对象,这种对象是output stream或者writer,就像某种API,它允许将DOM对象回写至client。
        为了支持这种风格的filter,container必须达到下面的要求。当filter在container filter chain的实现中调用doFilter方法时,container必须保证它传递给filter chain中下一个实体的request对象和response对象和当前调用的filter传递进doFilter方法的是同一个对象。
        当调用者包装request对象或response对象时,包装对象也有相同的要求作用于来自servlet or a filter to RequestDispatcher.forward or RequestDispatcher.include的调用。在这种情况下,被调用的servlet接收到的request和response对象必须和调用者servlet或filter传入的包装对象是相同的。

 

SRV.6.2.3 Filter Environment

在部署描述符中,可以使用<init-params>元素来关联filter的初始化参数。在运行时,这些参数的names和values对于filter来说可以通过filter的FilterConfig对象的getInitParameter和getInitParameterNames方法获得。另外,FilterConfig提供了对web application的ServletContext的访问功能,以便可以装载资源,提供日志功能,以及对ServletContext的attribute列表的存储。

 

SRV.6.2.4 Configuration of Filters in a Web Application

在部署描述符中,filter使用<filter>元素定义。在这个元素中,程序员应定义如以下描述:

  • filter-name:用来把filter映射到一个servlet或URL

  • filter-class:container使用它来定义filter的类型

  • init-params:filter的初始化参数

        还有一些可选的功能,程序员可以定义图标,文本的描述,and a display name for tool manipulation 。Container会按照部署描述符中所定义的,一个filter声明对应一个java class的实例。因此,如果开发者用同样的filter类定义了两个filter的声明,那么同一个filter class就会有两个实例被实例化。

        这里有一个filter声明的例子:SRV.6.2.4-1.png

        一旦在部署描述符中描述声明了一个filter,就需要使用<filter-mapping>元素来定义filter需要作用于的内容,它们可以是web application中的servlets和静态resources。比如,以下的代码片段把Image Filter filter到了ImageServlet这个servlet:SRV.6.2.4-2.png

        Filters可以关联至一组servlets和静态内容,通过<url-pattern>风格的filter mapping:SRV.6.2.4-3.png

        此处,Logging Filter被作用于web application中所有的servlets和静态内容,因为每个匹配“/*”的request URL。
        当使用<url-pattern>风格的元素去执行<filter-mapping>元素的时候,container必须判断request URL是否和<url-pattern>匹配,路径匹配规则参见SRV.11,“Mapping Requests to Servlets”。
        container在构建用来匹配某一特定request URL的filter chain时,其处理过程如下:

  1. 首先,<url-pattern>匹配filter mapping的顺序和出现在部署描述符中的顺序一致。

  2. 其次,<servlet-name>匹配filter mapping的顺序和出现在部署描述符中的顺序一致。

        这样的要求意味着container在接收到request时,会按照下面的内容处理reqeust:

  • 根据SRV.11.2 Specifications of Mappings提到的规则来识别目标web 资源。

  • 如果有filter与servlet name相匹配,并且web资源有<servlet-name>元素,container会依照部署描述符中声明的状态建立filter chain。The last filter in this chain corresponds to the last <servlet-name> matching filter and is the filter that invokes the target Web resource.

  • 如果有filter使用<url-pattern>匹配并且根据SRV.11.2 Specification of Mapping的规则url-pattern匹配request URL,container会依照部署描述符中声明的<url-pattern>的顺序建立chain。The last filter in this chain is the filter that invokes the first filter in the <servlet-name> matching chain, or invokes the target Web resource if there are none.

        高性能的web container会缓存filter chain以便它们不必基于每一个request去计算filter chain。

 

SRV.6.2.5 Filters and the RequestDispatcher

在Java servlet 规范v2.4中的关于filter的新增内容是,通过配置使filter可以在request dispatcher的forward()及include()之下被调用的能力。
        通过在部署描述符中使用新标签<dispatcher>元素,开发者可以在filter-mapping中指出,在以下情况出现的时候,他是否需要filter作用于request:

  1. request直接来自client。这种情况可以通过给<dispatcher>元素设置value为REQUEST来指明,或者不配置任何<dispatcher>元素。

  2. 在request dispatcher之下被执行的request表示web组件通过调用forward()来匹配<url-pattern>或者<servlet-name>。这种情况通过给<dispatch>元素设置value为FORWARD来声明。

  3. 在request dispatcher之下被执行的request表示web组件通过调用forward()来匹配<url-pattern>或者<servlet-name>。这种情况通过给<dispatch>元素设置value为INCLUDE来声明。

  4. Request被SRV.9.9 Error Handling描述的错误页面机制处理来匹配<url-pattern>。这种情况通过给<dispatch>元素设置value为ERROR来声明。

  5. 或者以上情况的任意组合。

举例说明:

        SRV.6.2.5-1.png

客户端以products/...开头的请求,都会触发Logging Filter的调用。但并不会触发request dispatcher的调用。再看下面的代码:

        SRV.6.2.5-2.png

客户端对ProductServlet的请求,都不会触发Logging Filter的调用,也不会在forward()到ProductServlet的时候被调用调用。只有request dispatcher 调用到ProductServlet并且执行include()方法时才会触发。
最终地,

        SRV.6.2.5-3.png

would result in the Logging Filter being invoked by client requests starting /products/... and underneath a request dispatcher forward() call where the request dispatcher has path commencing /products/... 。


© 著作权归作者所有

共有 人打赏支持
悟空太多啦
粉丝 20
博文 85
码字总数 70979
作品 1
南京
项目经理
AOP-style programming for Web applications

AOP-style programming for Web applications Dmitry Namiot dnamiot@servletsuite.com In this article we are demonstrating the usage of Java Servlets filters. Servlet filters are a ......

yaraja
2011/09/28
0
0
JPA/EJB3 Relationship

The Java Persistence API introduced in Java EE 5 is a subset of EJB 3 and replaces the persistence solution of EJB 2.0 CMP. JPA 1.0 has been defined as part of the EJB 3.0 speci......

Barudisshu
2014/09/21
0
0
图解 & 深入浅出 JavaWeb:Servlet必会必知

Writer :BYSocket(泥沙砖瓦浆木匠) 微 博:BYSocket 豆 瓣:BYSocket FaceBook:BYSocket Twitter :BYSocket “眨眼间,离上一篇写技术博文时隔1个月。怕自己真的生疏了,都是备案太慢惹...

泥沙砖瓦浆木匠
2015/08/21
0
50
图解 & 深入浅出 JavaWeb:Servlet必会必知

Writer :BYSocket(泥沙砖瓦浆木匠) 微 博:BYSocket 豆 瓣:BYSocket FaceBook:BYSocket Twitter :BYSocket “眨眼间,离上一篇写技术博文时隔1个月。怕自己真的生疏了,都是备案太慢惹...

KeepMoving
2015/08/25
0
0
J2EE规范系列之 JMS1.1 (一) 基本概念

什么是JMS JMS(Java Message Service) 即Java消息服务。它提供标准的产生、发送、接收消息的接口简化企业应用的开发。它是J2EE规范的一部分,定义的接口标准,针对不同的厂商有不同的实现库。...

Garrry
2015/07/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MySQL 乱七八糟的可重复读隔离级别实现

MySQL 乱七八糟的可重复读隔离级别实现 摘要: 原文可阅读 http://www.iocoder.cn/Fight/MySQL-messy-implementation-of-repeatable-read-isolation-levels 「shimohq」欢迎转载,保留摘要,谢...

DemonsI
今天
2
0
Spring源码阅读——2

在阅读源码之前,先了解下Spring的整体架构: 1、Spring的整体架构 1. Ioc(控制反转) Spring核心模块实现了Ioc的功能,它将类与类之间的依赖从代码中脱离出来,用配置的方式进行依赖关系描...

叶枫啦啦
今天
1
0
jQuery.post() 函数格式详解

jquery的Post方法$.post() $.post是jquery自带的一个方法,使用前需要引入jquery.js 语法:$.post(url,data,callback,type); url(必须):发送请求的地址,String类型 data(可选):发送给后台的...

森火
今天
0
0
referer是什么意思?

看看下面这个回答(打不开网页可以把网址复制到搜索栏): https://zhidao.baidu.com/question/577842068.html

杉下
今天
1
0
使用U盘安装CentOS-解决U盘找不到源

1. 使用UltraISO制作CentOS安装盘 如果需要安装带界面的系统,为保证安装顺利,可选择Everything版本的ISO制作安装盘。 2. 在BIOS中选择使用U盘安装 系统启动后,进入安装选择界面,其中有三...

Houor
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部