在 servlet 生成大量下载时防止客户端超时

Prevent client timing out while a servlet generates a large download

我有一个 Java servlet,它可以生成一些任意的报告文件,并且 returns 它可以下载到用户的浏览器。该文件直接写入 servlet 的输出流,因此如果它非常大,则可以分块成功下载。然而,有时生成的数据不够大,无法拆分成块,客户端连接超时,或者它运行成功但下载不会出现在浏览器的 UI 中,直到 100% 完成。

这是我的 servlet 代码的样子:

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("application/pdf");
    response.setHeader("Content-Disposition", "attachment; filename=\"" + report.getFileName(params) + "\"");

    try(OutputStream outputStream = response.getOutputStream()) {
        // Send the first response ASAP to suppress client timeouts
        response.flushBuffer(); // This doesn't seem to change anything??

        // This calls some arbitrary function that writes data directly into the given stream
        generateFile(outputStream);
    }
}

我 运行 一个特别糟糕的测试,文件生成花费了 110,826 毫秒。一旦结束,客户端下载了一个 0 字节的文件——我认为这是超时的结果。我希望这个特定的结果在 10 到 30 KB 之间——小于 servlet 的缓冲区。当我 运行 另一个测试时,它很快生成了大量数据(总共高达 80MB),因此在第一个块填满后下载出现在我的浏览器中。

有没有办法在生成任何实际数据之前强制将下载的文件显示在浏览器中(并防止发生超时)? flushBuffer() 通话是否正确?

好吧,看来通过 response.setBufferSize(1000); 缩小我的输出缓冲区的大小让我的压力测试文件能够成功下载。我仍然不知道为什么 response.flushBuffer() 似乎没有做任何事情,但至少只要我足够快地生成数据以在超时之前填充该缓冲区大小,下载就会完成。