文档章节

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
南京
项目经理
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
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
web.xml中load-on-startup的含义

<servlet-mapping> <servlet-name>proResponse</servlet-name> <url-pattern>/test</url-pattern> </servlet-mapping> <servlet> <servlet-name>proResponse</servlet-name> <servlet-class>......

2012/02/21
0
0
web.xml中load-on-startup标签的含义

在servlet的配置当中,<load-on-startup>5</load-on-startup>的含义是: 标记容器是否在启动的时候就加载这个servlet。 当值为0或者大于0时,表示容器在应用启动时就加载这个servlet; 当是一...

随智阔
2014/04/02
0
0
图解 & 深入浅出 JavaWeb:Servlet必会必知

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

泥沙砖瓦浆木匠
2015/08/21
0
50

没有更多内容

加载失败,请刷新页面

加载更多

【大福利】极客时间专栏返现二维码大汇总

我已经购买了如下专栏,大家通过我的二维码你可以获得一定额度的返现! 然后,再给大家来个福利,只要你通过我的二维码购买,并且关注了【飞鱼说编程】公众号,可以加我微信或者私聊我,我再...

飞鱼说编程
今天
1
0
Spring5对比Spring3.2源码之容器的基本实现

最近看了《Spring源码深度解析》,该书是基于Spring3.2版本的,其中关于第二章容器的基本实现部分,目前spring5的实现方式已有较大改变。 Spring3.2的实现: public void testSimpleLoad(){...

Ilike_Java
今天
1
0
【王阳明心学语录】-001

1.“破山中贼易,破心中贼难。” 2.“夫万事万物之理不外于吾心。” 3.“心即理也。”“心外无理,心外无物,心外无事。” 4.“人心之得其正者即道心;道心之失其正者即人心。” 5.“无...

卯金刀GG
今天
2
0
OSChina 周三乱弹 —— 我们无法成为野兽

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ _刚刚好: 霸王洗发水这波很骚 手机党少年们想听歌,请使劲儿戳(这里) hahahahahahh @嘻酱:居然忘了喝水。 让你喝可乐的话, 你准忘不了...

小小编辑
今天
11
0
vm GC 日志 配置及查看

-XX:+PrintGCDetails 打印 gc 日志 -XX:+PrintTenuringDistribution 监控晋升分布 -XX:+PrintGCTimeStamps 包含时间戳 -XX:+printGCDateStamps 包含时间 -Xloggc:<filename> 可以将数据保存为......

Canaan_
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部