【发布时间】:2011-01-04 16:23:24
【问题描述】:
在Filter.doFilter 方法中,我调用了chain.doFilter。
doFilter 在 doFilter 中做什么?不是递归调用吗?
【问题讨论】:
标签: java servlet-filters
在Filter.doFilter 方法中,我调用了chain.doFilter。
doFilter 在 doFilter 中做什么?不是递归调用吗?
【问题讨论】:
标签: java servlet-filters
Servlet 过滤器是 Chain of responsibility 设计模式的实现。
所有过滤器都是链接的(按照它们在 web.xml 中的定义顺序)。 chain.doFilter() 正在处理链中的下一个元素。链的最后一个元素是目标资源/servlet。
【讨论】:
它调用的是chain对象的doFilter方法,而不是它本身,所以不,它不会是递归的。
chain 这个名字表明你有一个过滤器序列,每个过滤器做一些处理,然后依次传递给下一个过滤器,所以每个对象都有一个chain 成员指向下一个过滤器序列,在过滤器执行完自己的处理后调用。序列中的最后一个可能会将null 作为chain 值,或者它自己知道它是序列中的最后一个。
【讨论】:
它在内部调用过滤器链中下一个过滤器的doFilter,当链结束时,它调用目标servlet。
【讨论】:
没有你所说的任何代码,我只能假设你是这样的:
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()。正如另一个答案中提到的,这是众所周知的责任链设计模式。
【讨论】:
通过调用chain.doFilter,您将请求/响应交给过滤器链中的下一个过滤器。如果您不调用它,则不会执行下一个过滤器(可能在您的 web.xml 中定义)。
如果您只是调用 doFilter,那么是的,您将拥有无限递归和堆栈溢出。但是,您正在调用 filterChain 对象的 doFilter 方法,该方法指示它执行下一个过滤器。
【讨论】:
导致调用链中的下一个过滤器,或者如果调用过滤器是链中的最后一个过滤器,则导致调用链末尾的资源。
【讨论】:
是的,准确地说是递归调用。如果您将过滤器设置为这样的文件夹,
/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 模式定义过滤器映射。
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
路径 /* 中的所有资源最终将被过滤器实现中的 doFilter(...) 方法调用,但最有趣的是,FilterChain 中的 doFilter 将执行请求/响应的实际处理。 因此,如果您不调用 chain.doFilter(...) 那么您的响应可能会被破坏。
【讨论】: