原文地址:
http://otndnld.oracle.co.jp/document/products/as10g/101300/B25221_03/web.1013/b14426/filters.htm#BCFDIHEJ
文本回答了 1 . filter 和sevlet的执行顺序 2. filter责任链( FilterChain
) 终点会执行target servlet
通过这两点很容易就能明白,filter比sevlet更灵活,servlet其实是一个特殊的filter(虽然是现有servlet,后有filter), struts 2就是用filter实现了servlet的功能;
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.
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:
-
The target servlet is requested. The container detects that there are two filters and creates the filter chain.
-
The first filter in the chain is invoked by its
doFilter()
method. -
The first filter completes any preprocessing, then calls the
doFilter()
method of the filter chain. This results in the second filter being invoked by itsdoFilter()
method. -
The second filter completes any preprocessing(前处理), then calls the
doFilter()
method of the filter chain. This results in the target servletbeing invoked by itsservice()
method.这个是重点,filter 责任链(
FilterChain
), 的终点是 servlet ,执行完servlet后逐层返回,类似递归调用逐层返回;Request在chain
doFilter()
之前处理, 对reponse处理在chaindoFilter()之后,servlet执行完返回了response结果 ;
在servlet 3.0 final specification 的第6.2.1节 filter Life第7点就明确说明了
chain FilterChain的最后会调用target servlet ecycle 中说到了7点应用, -
When the target servlet is finished, the chain
doFilter()
call in the second filter returns, and the second filter can do anypostprocessing(后处理). -
When the second filter is finished, the chain
doFilter()
call in the first filter returns, and the first filter can do any postprocessing. -
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
doFilter()
有三种典型应用:
1. 对request处理,需要构造一个 wrapper for the request
2. 对reponse处理,需要构造一个wrapper for the response
3. 如果需要继续玩下传,利用chain.filter() ,如果想终止request,不要调用 chain.filter();
值得注意的是 在servlet调用之前的处理代码必须要放在chain.filter()之前, servlet之后调用的代码必须要放在chain.filter之后.filter可以包裹在servlet的前后,这种前后位置造成的重要区别有点类似树的遍历(前序,后序,中序遍历)