chain.doFilter()
继续到链中的下一个元素。 链的最后一个元素是目标资源/Servlet。它调用chain
对象的doFilter
方法,而不是自身,因此不会发生递归。
名称chain
表明您有一系列过滤器,每个过滤器都要进行一些处理,然后传递给序列中的下一个过滤器,因此每个对象都有一个chain
成员指向序列中的下一个过滤器,在该过滤器执行自己的处理后被调用。序列中的最后一个过滤器可能会将chain
值设置为null
,或者它自己知道它是序列中的最后一个。
没有你所说的任何代码,我只能假设你是指:
class Filter implements FilterAPI {
private FilterAPI chain;
FilterAPI(FilterAPI chain) { this.chain = chain; }
@override void doFilter (Set setToFilter) {
// do some filtering on setToFilter
chain.doFilter(setToFilter);
}
}
如果是这种情况,那么你并没有递归调用任何东西,而是在不同的对象上调用doFilter()。正如另一个答案中所提到的那样,这是众所周知的“责任链”设计模式。
在内部,它会调用过滤器链中下一个过滤器的doFilter
方法,当链结束时,它会调用目标servlet。
使链中的下一个过滤器被调用,或者如果调用的过滤器是链中的最后一个过滤器,则导致链末端的资源被调用。
是的,确切地说,这是一个递归调用。如果您将筛选器设置为文件夹,则会出现这种情况,
/javax.faces.resource/*
然后这个文件夹中的所有资源将被递归调用。所以如果你想对资源做一些操作,你需要编写以下代码:
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
doSomething(request, response);
chain.doFilter(request, response);
}
调用chain.doFilter(...)将处理当前请求/响应,然后调用下一个资源的doFilter,直到url-pattern中的所有资源都被后续的doFilter()调用处理。
假设您有一个ImagesFilter和SessionFilter实现。对于这些过滤器实现,您将使用URL-pattern定义filter-mapping。
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
路径 /* 中的所有资源都将由您的过滤器实现中的 doFilter(...) 方法调用,但最有趣的是 FilterChain 中的 doFilter 将执行请求/响应的实际处理。因此,如果您不调用 chain.doFilter(...),则可能会破坏您的响应。