doFilter调用两次,打算行为?

use*_*661 11 java servlets glassfish java-ee servlet-filters

我正在研究Java EE servlet教程并尝试了心情示例.我注意到,一旦servlet调用在链中,第二次不是,就会调用doFilter两次.

我在TimeOfDayFilter.java和MoodServlet.java中添加了一些printlns来显示它.

TimeOfDayFilter.java:

    ...
    System.out.println("TimeOfDay before"); //added
    chain.doFilter(req, res);
    System.out.println("TimeOfDay after"); //added
    ...
Run Code Online (Sandbox Code Playgroud)

MoodServlet.java:

    ...
    response.setContentType("text/html;charset=UTF-8");

    System.out.println("MoodServlet"); //added

    PrintWriter out = response.getWriter();
    ...
Run Code Online (Sandbox Code Playgroud)

调用servlet时glassfish服务器(3.1)窗口的结果如下:

    INFO: mood was successfully deployed in 406 milliseconds.
    INFO: TimeOfDay before
    INFO: MoodServlet
    INFO: TimeOfDay after
    INFO: TimeOfDay before
    INFO: TimeOfDay after
Run Code Online (Sandbox Code Playgroud)

这是预期的行为吗?如果是这样,额外通话的原因是什么?

Raj*_*tra 5

chain.doFilter(request,response);
Run Code Online (Sandbox Code Playgroud)

这会将控制权传递给与过滤器关联的servlet。但是,在执行了相应的servlet之后,控件将在上一行的末尾返回,然后执行当前doFilter()中的所有行。

如果您想将控件永久传递给Servlet,而不是让它返回过滤器,只需添加一个

return;
Run Code Online (Sandbox Code Playgroud)

在当前过滤器的chain.doFilter(request,response)行的末尾。

  • 此答案不会以任何方式解释问题中描述的症状。 (3认同)

Zee*_*lal 1

是的,Filter 在生命周期中执行两次,第一次是在客户端请求到达 servlet 时调用,第二次是在 servlet 执行后向客户端提供响应时调用。

执行顺序在某种程度上看起来像这样。

过滤器生命周期

  • 这个答案纯属无稽之谈。请修复或删除它。所有这些由无知的白痴产生的赞成票都会误导未来的读者。 (13认同)
  • @Zeeshan Bilal:我认为你的答案是错误的。对于每个请求,doFilter 方法都会被调用一次。doFilter 中的语句将一直执行,直到到达“chain.doFilter(req, resp)”。“chain.doFilter(req, resp)”导致链中或 servlet 中的下一个过滤器继续执行。执行过滤器和 servlet 序列后,doFilter 方法在“chain.doFilter(req, resp)”之后继续。 (4认同)
  • 感谢您的回答,但还有几个问题: - 人们也可以将响应箭头解释为 chain.doFilter 调用之后发生的代码(如我的代码片段中打印“TimeOfDay after”的行),但它真的是过滤器 DoFilter 方法的新调用吗?- 有没有办法确定它是第一次还是第二次被调用(请求或响应部分)?- 有没有办法在回来的路上不接电话? (2认同)