Tomcat不会刷新响应缓冲区

时间:2012-03-29 07:53:23

标签: java tomcat servlets tomcat7

我在下面的HttpResponse#flushBuffer上测试了PrintWriter#flushTomcat 7,但似乎响应忽略了它们,而不是像预期的那样在线上刷新内容。

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        PrintWriter pw = response.getWriter();
        pw.println("say hi now");
        pw.flush();
        response.flushBuffer();
        try {
            Thread.sleep(5000);
        } catch (Exception e) {
        }
        pw.println("say bye in 5 seconds");

    }

}

在延迟之后,浏览器一起显示“hi”和“bye”。这是不正当行为还是打算?

@EDIT

根据@Tomasz Nurkiewicz的建议,我再次使用curl进行测试,然后问题就消失了。似乎标准浏览器和来自同一http响应的tcp/ip monitor打包small pieces of contents将它们组合在一起。

@EDIT 2

还观察到HttpResponse#flushBufferPrintWriter#flush驱逐Tomcat 7以发送客户chunked data

4 个答案:

答案 0 :(得分:5)

我刚才有同样的问题。要阻止浏览器等待页面完成加载,然后才能进行任何渲染,您需要从:

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

答案 1 :(得分:2)

flushBuffer()的API非常精确:

  

强制将缓冲区中的任何内容写入客户端。对此方法的调用会自动提交响应,这意味着将写入状态代码和标题。

因此,根据规范没有实现Tomcat(缓冲区更积极,如果它们太小则保持刷新),或者客户端(浏览器)在实际渲染之前等待更多输入。

您可以尝试使用nc吗?

答案 2 :(得分:2)

我也有这个问题。我也发现问题随着卷曲而消失。 通过一些嗅探,结果证明罪魁祸首是gzip编码。为了压缩响应,gzip等待直到底层PrintWriter关闭(即,直到写入完整响应),然后产生压缩输出。在客户端,这意味着在完整响应准备好之前,您不会得到任何回复。另一方面,Curl不会向服务器发出Accept-Encoding:gzip,这就是为什么这个工作正常,你可以按预期正常获取分块输出。

答案 3 :(得分:0)

这种现象的一个尚未提及的可能原因是反病毒软件。我确实在我的机器上观察到相同的行为:服务器发送分块数据,curl工作,普通浏览器没有,并且Fiddler也证实它不是被阻止的服务器。所以过了一段时间我怀疑Sophos(我的雇主使用的防病毒软件)的网络保护干扰,事实上他们在https://community.sophos.com/kb/en-us/115656确认他们阻止了分块数据直到响应完成,除了某些哑剧 - 经常用于流媒体数据的类型。

作为快速检查,可以在http://www.pushlets.com运行HTTP-Push演示。如果它不起作用,很可能客户端在处理text / html类型的分块数据方面存在一般性问题。