【问题标题】:Servlet Filter acts ambiguously?Servlet过滤器行为模棱两可?
【发布时间】:2012-08-14 03:20:18
【问题描述】:

在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 秒后发球。 为什么过滤器会出现这种歧义?

【问题讨论】:

    标签: jsp tomcat servlets webserver servlet-filters


    【解决方案1】:

    在 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 秒再显示任何内容(这可能取决于您实际发送的内容)。

    【讨论】:

    • 您可以通过显式关闭与响应关联的输出流(或写入器)来释放客户端,但我认为这不能保证。
    猜你喜欢
    • 1970-01-01
    • 2020-06-03
    • 2011-01-09
    • 2012-06-09
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多