Overview of How Filters Work

This section provides an overview of the following topics:

How the Servlet Container Invokes Filters

Figure 5-1 shows, on the left, a scenario in which no filters are configured for the servlet being requested. On the right, several filters (1, 2, ..., N) have been configured.

Figure 5-1 Servlet Invocation with and without Filters

 
Description of the illustration invfilt.gif

Each filter implements the javax.servlet.Filter interface, which includes a doFilter() method that takes as input a request and response pair along with a filter chain, which is an instance of a class (provided by the servlet container) that implements the javax.servlet.FilterChain interface. The filter chain reflects the order of the filters. The servlet container, based on the configuration order in the web.xml file, constructs the chain of filters for any servlet or other resource that has filters mapped to it. For each filter in the chain, the filter chain object passed to it represents the remaining filters to be called, in order, followed by the target servlet.

The FilterChain interface also specifies a doFilter() method, which takes a request and response pair as input and is used by each filter to invoke the next entity in the chain.

Also see "Standard Filter Interfaces".

If there are two filters, for example, the key steps of this mechanism would be as follows:

  1. The target servlet is requested. The container detects that there are two filters and creates the filter chain.

  2. The first filter in the chain is invoked by its doFilter() method.

  3. The first filter completes any preprocessing, then calls the doFilter() method of the filter chain. This results in the second filter being invoked by its doFilter() method.

  4. The second filter completes any preprocessing, then calls the doFilter() method of the filter chain. This results in the target servlet being invoked by its service() method.

  5. When the target servlet is finished, the chain doFilter() call in the second filter returns, and the second filter can do any postprocessing.

  6. When the second filter is finished, the chain doFilter() call in the first filter returns, and the first filter can do any postprocessing.

  7. When the first filter is finished, execution is complete.

None of the filters are aware of their order. Ordering is handled entirely through the filter chain, according to the order in which filters are configured in web.xml.

Typical Filter Actions

The following are among the possible actions of the doFilter() method of a filter:

  • Create a wrapper for the request object to allow input filtering. Process the content or headers of the request wrapper as desired.

  • Create a wrapper for the response object to allow output filtering. Process the content or headers of the response wrapper as desired.

  • Pass the request and response pair (or wrappers) to the next entity in the chain, using the chain doFilter() method. Alternatively, to block request processing, do not call the chain doFilter() method.

Any processing you want to occur before the target resource is invoked must be prior to the chain doFilter() call. Any processing you want to occur after the completion of the target resource must be after the chain doFilter() call. This can include directly setting headers on the response.

Note that if you want to preprocess the request object or postprocess the response object, you cannot directly manipulate the original request or response object. You must use wrappers. When postprocessing a response, for example, the target servlet has already completed and the response could already be committed by the time a filter would have a chance to do anything with the response. You must pass a response wrapper instead of the original response in the chain doFilter() call. See "Using a Filter to Wrap and Alter the Request or Response".

Standard Filter Interfaces

A servlet filter implements the javax.servlet.Filter interface. The main method of this interface, doFilter(), takes a javax.servlet.FilterChain instance, created by the servlet container to represent the entire chain of filters, as input. The initialization method of the Filter interface, init(), takes a filter configuration object, which is an instance of javax.servlet.FilterConfig, as input. This section briefly describes the methods specified in these interfaces.

For additional information about the interfaces and methods discussed here, refer to the Sun Microsystems Javadoc for the javax.servlet package, at:

http://java.sun.com/j2ee/1.4/docs/api/index.html

Methods of the Filter Interface

The Filter interface specifies the following methods to implement in your filters:

  • void init(FilterConfig filterConfig)

    The servlet container calls init() as a filter is first instantiated and placed into service. This method takes a javax.servlet.FilterConfig instance as input, which the servlet container uses to pass information to the filter during the initialization. Include any special initialization requirements in your implementation. Also see "Methods of the FilterConfig Interface".

  • void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

    This is where your filter processing occurs. Each time a target resource (such as a servlet or JSP page) is requested, where the target resource is mapped to a chain of one or more filters, the servlet container calls the doFilter() method of each filter in the chain, in order according to web.xml filter configurations. (See "Construction of the Filter Chain".) Within the doFilter() processing of a filter, invoke the doFilter() method on the filter chain object that is passed in to the doFilter() method of the filter. (An exception to this is if you want to block request processing.) This is what leads to invocation of the next entity in the chain (either the next filter, or the target servlet if this is the last filter in the chain) after a filter has completed.

  • destroy(): The servlet container calls destroy() after all execution of the filter has completed (all threads of the doFilter() method have completed, or a timeout has occurred) and the filter is being taken out of service. Include any special cleanup requirements in your implementation.

Configure the Filter

This section lists the steps in configuring a servlet filter. Do the following in web.xml for each filter:

  1. Declare the filter through a <filter> element and its subelements, which maps the filter class (including package) to a filter name. For example:

    <filter>
    <filter-name>timer</filter-name>
    <filter-class>filter.TimerFilter</filter-class>
    </filter>

    You can optionally specify initialization parameters here, similarly to how you would for a servlet:

    <filter>
    <filter-name>timer</filter-name>
    <filter-class>filter.TimerFilter</filter-class>
    <init-param>
    <param-name>name</param-name>
    <param-value>value</param-value>
    <init-param>
    </filter>
  2. Using a <filter-mapping> element and its subelements, map the filter name to a servlet name or URL pattern to associate the filter with the corresponding resource (such as a servlet or JSP page) or resources. For example, to have the filter invoked whenever the servlet of name myservlet is invoked:

    <filter-mapping>
    <filter-name>timer</filter-name>
    <servlet-name>myservlet</servlet-name>
    </filter-mapping>

    Or, to have the filter invoked whenever sleepy.jsp is requested, according to URL pattern:

    <filter-mapping>
    <filter-name>timer</filter-name>
    <url-pattern>/sleepy.jsp</url-pattern>
    </filter-mapping>

    Note that instead of specifying a particular resource in the <url-pattern> element, you can use wild card characters to match multiple resources, such as in the following example:

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

The filter name can be arbitrary, but preferably is meaningful. It is simply used as the linkage in mapping a filter class to a servlet name or URL pattern.

If you configure multiple filters that apply to a resource, they will be entered in the servlet chain according to their declaration order in web.xml, and they will be invoked in that order when the target servlet is requested. See the next section, "Construction of the Filter Chain".

Note:

There are additional steps to configure a filter for a forward or include target. See "Filtering Forward or Include Targets".

Construction of the Filter Chain

When you declare and map filters in web.xml, the servlet container determines which filters apply to each servlet or other resource (such as a JSP page or static page) in the Web application. Then, for each servlet or resource, the servlet container builds a chain of applicable filters, according to your web.xmlconfiguration order, as follows:

    1. First, any filters that match a servlet or resource according to a <url-pattern> element are placed in the chain, in the order in which the filters are declared in web.xml.

    2. Next, any filters that match a servlet or resource according to a <servlet-name> element are placed in the chain, with the first <servlet-name> match following the last <url-pattern> match.

    3. Finally, the target servlet or other resource is placed at the end of the chain, following the last filter with a <servlet-name> match.

Java servlet filter chain order

The servlet API allows servlet filters to be inserted into the processing cycle to form a Filter Chain. How is a chain defined, and what is the ordering of filters in the chain?

The servlet filter chain is formed by defining multiple filters for the same servlet or URL pattern in web.xml. The order in which the filters are invoked is the same order as <filter-mapping>s appear in the web.xml file.

For example, if this is defined in web.xml:

<!-- Filter mapping -->
<filter-mapping>
<filter-name>servletFilter2</filter-name>
<servlet-name>filterdemo</servlet-name>
</filter-mapping> <filter-mapping>
<filter-name>servletFilter</filter-name>
<servlet-name>filterdemo</servlet-name>
</filter-mapping>

then servletFilter2 will be applied before servletFilter.

Actually, it's more accurate to imagine these filters as layers or wraps instead of chains. In the above example, servletFilter2 wraps servletFilter.

Using a Filter to Wrap and Alter the Request or Response

Particularly useful functions for a filter are to manipulate a request, or manipulate the response to a request. To manipulate a request or response, you must create a wrapper. You can use the following general steps:

  1. To manipulate requests, create a class that extends the standard javax.servlet.http.HttpServletRequestWrapper class. This class will be your request wrapper, allowing you to modify a request as desired.

  2. To manipulate responses, create a class that extends the standard javax.servlet.http.HttpServletResponseWrapper class. This class will be your response wrapper, allowing you to modify a response after the target servlet or other resource has delivered and possibly committed it.

  3. Optionally create a class that extends the standard javax.servlet.ServletOutputStream class, if you want to add custom functionality to an output stream for the response.

  4. Create a filter that uses instances of your custom classes to alter the request or response as desired.

The next section, "Response Filter Example", provides an example of a filter that alters the response.

Response Filter Example

This example employs an HTTP servlet response wrapper that uses a custom servlet output stream. This functionality allows the wrapper to manipulate the response data after the target HTML page is finished writing it out. Without using a wrapper, you cannot change the response data after the servlet output stream has been closed (essentially, after the servlet has committed the response). That is the reason for implementing a filter-specific extension to the ServletOutputStream class in this example.

This example uses the following custom classes:

  • GenericResponseWrapper: Extends HttpServletResponseWrapper for custom functionality in manipulating an HTTP response.

  • FilterServletOutputStream: Extends ServletOutputStream to provide custom functionality for use in the response wrapper.

  • MyGenericFilter: This class is for a generic, empty ("pass-through") filter that is used as a base class.

  • PrePostFilter: Extends MyGenericFilter and implements doFilter() code to alter the HTTP response, inserting a line before the HTML page output and a line after the HTML page output.

Understanding and Using Servlet Filters的更多相关文章

  1. Understanding ASP.NET MVC Filters and Attributes

    这篇文章把Asp.net MVC的filter介绍的很详细,值得收藏. http://www.dotnet-tricks.com/Tutorial/mvc/b11a280114-Understandi ...

  2. How to define Servlet filter order of execution using annotations

    If we define Servlet filters in web.xml, then the order of execution of the filters will be the same ...

  3. Struts2 中添加 Servlet

    Struts2中如何添加Servlet 以前Java开发都是Servlet的天下,如今是各种框架横行,遇到一个需要将以前的Servlet加入到现有的Struts2的环境中. Google之后发现Sta ...

  4. 两个Web应用必须的Servlet Filter

    其实原文是一个英文文章“Two Servlet Filters Every Web Application Should Have” 文章说了2个Filter: GzipFilter ChcheFil ...

  5. Servlet Life Cycle

    Servlet Life Cycle http://docs.oracle.com/javaee/5/tutorial/doc/bnafi.html Servlet Filters and Event ...

  6. SpringMVC中为什么要配置Listener和Servlet

    一直以来,我们使用SpringMVC的时候习惯性都配置一个ContextLoaderListener,虽然曾经有过疑问,配置的这个监听器和Servlet究竟做了什么,但也没深究. 要说任何Web框架都 ...

  7. 试译 Understanding Delta-Sigma Modulators

         接触Σ-Δ调制的时候发现国内有关的资料比较匮乏,因为缺乏了解还有一些人把其中的原理吹得神乎其神难以理解.其实Σ-Δ调制的原理是很简单.逻辑上很自然的,可以定性理解成传统ADC/DAC量化的是 ...

  8. Java性能提示(全)

    http://www.onjava.com/pub/a/onjava/2001/05/30/optimization.htmlComparing the performance of LinkedLi ...

  9. Chapter 4: Spring and AOP:Spring's AOP Framework -- draft

    Spring's AOP Framework Let's begin by looking at Spring's own AOP framework - a proxy-based framewor ...

随机推荐

  1. HTML5标准终于来了,看什么书学习最好??????

    最近看了一本书<HTML5网页开发实例详解>,是大众点评的攻城狮写的,觉得很有收获,看样子目前大多数的国内网页都支持HTML5了,全栈工程师是不是必须得会HTML5? 有兴趣的可以讨论呀, ...

  2. josephus问题

    问题描述 n个人围成一圈,号码为1-n,从1开始报数,报到2的退出,剩下的继续从1开始报数,求最后一个人的号码. 算法分析 最直观的算法是用循环链表模拟.从首节点开始,不断删除第二个节点,直到只剩一个 ...

  3. 数据库连接字符串大全 资料引用:http://www.knowsky.com/339545.html

    转自:http://www.connectionstrings.com/ • SQL Server • ODBC ◦ Standard Security: "Driver={SQL Serv ...

  4. 不同浏览器的DNS超时重发机制(一)

    一.Chrome浏览器(37.0.2062.124 m) 1.在Win7环境下,DNS超时重发的时间间隔为:2s.2s.2s.2s(在这个时刻重复发2个DNS请求).2s.4s,再经过大约14s左右, ...

  5. 已成功与服务器建立连接,但是在登录前的握手期间发生错误。 (provider: SSL Provider, error: 0 - 等待的操作过时)

    今天忽然间发现远程连接别人数据库会出现  已成功与服务器建立连接,但是在登录前的握手期间发生错误. (provider: SSL Provider, error: 0 - 等待的操作过时)  这种情况 ...

  6. 关于Protobuf在游戏开发中的运用

    最近在研究protobuf在项目中的使用,由于我们项目服务端采用的是C++,客户端是cocos2dx-cpp,客户端与服务端的消息传输是直接对象的二进制流.如果客户端一直用C++来写,问题到不大,但是 ...

  7. PHP 网站保存快捷方式的实现代码

    介绍下使用PHP实现网站快捷方式的保存方法. PHP怎么实现网站保存快捷方式呢?下面是一段PHP代码,下面这段代码,可以PHP实现网站保存快捷方式,以便用户随时浏览.  <?php  /** * ...

  8. 实现Server.UrlEncode和Server.UrlDecode功能的js代码

    <script> var EncodeURI = function(unzipStr,isCusEncode){    if(isCusEncode){        var zipArr ...

  9. uWSGI uwsgi_response_write_body_do(): Connection reset by peer 报错的解决方法

    服务器架构是:Nginx+uWSGI+Django 某一天,发现服务器返回的response不完整,例如文档大小是200K的,但是只返回了100K给浏览器. 查了一下uWSGI的日志,发现以下错误: ...

  10. 【转】 管理CPU 亲和性

    简单地说,CPU 亲和性(affinity) 就是进程要在某个给定的 CPU 上尽量长时间地运行而不被迁移到其他处理器的倾向性.Linux 内核进程调度器天生就具有被称为 软 CPU 亲和性(affi ...