【问题标题】:What is chain.doFilter doing in Filter.doFilter method?chain.doFilter 在 Filter.doFilter 方法中做了什么?
【发布时间】:2011-01-04 16:23:24
【问题描述】:

Filter.doFilter 方法中,我调用了chain.doFilter

doFilterdoFilter 中做什么?不是递归调用吗?

【问题讨论】:

标签: java servlet-filters


【解决方案1】:

Servlet 过滤器是 Chain of responsibility 设计模式的实现。

所有过滤器都是链接的(按照它们在 web.xml 中的定义顺序)。 chain.doFilter() 正在处理链中的下一个元素。链的最后一个元素是目标资源/servlet。

【讨论】:

  • 嗨@Bozho,我可以在doFilter方法中添加另一个filter.doFilter()吗?
【解决方案2】:

它调用的是chain对象的doFilter方法,而不是它本身,所以不,它不会是递归的。

chain 这个名字表明你有一个过滤器序列,每个过滤器做一些处理,然后依次传递给下一个过滤器,所以每个对象都有一个chain 成员指向下一个过滤器序列,在过滤器执行完自己的处理后调用。序列中的最后一个可能会将null 作为chain 值,或者它自己知道它是序列中的最后一个。

【讨论】:

    【解决方案3】:

    它在内部调用过滤器链中下一个过滤器的doFilter,当链结束时,它调用目标servlet。

    【讨论】:

      【解决方案4】:

      没有你所说的任何代码,我只能假设你是这样的:

      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()。正如另一个答案中提到的,这是众所周知的责任链设计模式。

      【讨论】:

      • 这似乎是c#,这篇文章被标记为java。然而,答案仍然是正确的。
      • 我相信以上是有效的Java代码?我只是修复了构造函数的名称……
      • 可能是,我很困惑,因为我从未在 java.servlet.Filter 中见过 filterAPI 接口。或许这只是我自己的无知。 FilterAPI 来自哪里?
      • FilterAPI 只是一个虚构的名字……Filter 的 API ;-)
      【解决方案5】:

      通过调用chain.doFilter,您将请求/响应交给过滤器链中的下一个过滤器。如果您不调用它,则不会执行下一个过滤器(可能在您的 web.xml 中定义)。

      如果您只是调用 doFilter,那么是的,您将拥有无限递归和堆栈溢出。但是,您正在调用 filterChain 对象的 doFilter 方法,该方法指示它执行下一个过滤器。

      【讨论】:

        【解决方案6】:

        导致调用链中的下一个过滤器,或者如果调用过滤器是链中的最后一个过滤器,则导致调用链末尾的资源。

        【讨论】:

          【解决方案7】:

          是的,准确地说是递归调用。如果您将过滤器设置为这样的文件夹,

          /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(...) 那么您的响应可能会被破坏。

          【讨论】:

            猜你喜欢
            • 2018-10-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-07-21
            • 2012-02-07
            • 2014-08-23
            • 2019-01-28
            相关资源
            最近更新 更多