1

在 servlet 过滤器中, filterChain.doFilter(request, response); 应该将请求传递给链中的下一个。但请考虑以下两个代码:
代码 1:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException 
{
filterChain.doFilter(request, response);
try
{
Thread.sleep(20000);
}
catch(Exception e)
{
}            
}

代码 2:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException 
{
try
{
Thread.sleep(20000);
}
catch(Exception e)
{
}      
filterChain.doFilter(request, response);      
}

两个过滤器的执行方式相同。即在服务请求之前两者都需要 20 秒。
但实际上应该发生的是Code1应该立即发球并且Code2应该在 20 秒后发球。为什么过滤器中有这种歧义?

4

1 回答 1

3

在 servlet 或过滤器中休眠总是一个坏主意,因为 HTTP 工作线程是稀缺资源,因此您不应该阻止它们。但是在您的特定示例中,有希望。

基本上,您在 servlet 中打印或过滤到输出的任何内容都会被隐式缓冲以提高性能。如果您在 servlet/filter 中打印足够的数据,则 servlet 容器将刷新缓冲区,并且您的部分响应将到达客户端。但您也可以手动冲洗!

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
    filterChain.doFilter(request, response);
    response.flushBuffer();
    Thread.sleep(20000);
}

flushBuffer()指令强制容器刷新输出缓冲区。所有响应标头以及您从 servlet 发送的任何内容都将发送到客户端。但这里有一个问题:客户端将接收数据,但 HTTP 连接在接下来的 20 秒内保持打开状态。我对此进行了测试curl,它按预期工作。但是当在浏览器中使用相同的 URL 时(在 Opera、Firefox 和 Google Chrome 上测试),浏览器会等待 20 秒再显示任何内容(这可能取决于您实际发送的内容)。

于 2012-08-17T17:19:37.577 回答