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

Java 防止servlet生成大量下载时客户端超时,java,http,servlets,Java,Http,Servlets,我有一个Javaservlet,它生成一些任意的报告文件,并将其作为下载返回到用户的浏览器。该文件直接写入servlet的输出流,因此如果它非常大,则可以成功地分块下载。但是,有时生成的数据不够大,无法分割成块,或者客户端连接超时,或者客户端连接成功运行,但下载直到100%完成才显示在浏览器的UI中 这就是我的servlet代码的样子: @Override protected void doPost(HttpServletRequest request, HttpServletResponse

我有一个Javaservlet,它生成一些任意的报告文件,并将其作为下载返回到用户的浏览器。该文件直接写入servlet的输出流,因此如果它非常大,则可以成功地分块下载。但是,有时生成的数据不够大,无法分割成块,或者客户端连接超时,或者客户端连接成功运行,但下载直到100%完成才显示在浏览器的UI中

这就是我的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);
    }
}
我运行了一个特别糟糕的测试,文件生成耗时110826ms。当它结束时,客户端下载了一个0字节的文件-我想这是超时的结果。我期望这个特定的结果在10到30KB之间——比servlet的缓冲区小。当我运行一个不同的测试时,它很快生成了大量数据(总计80MB),因此在第一个数据块填满后,下载出现在我的浏览器中


在生成任何实际数据之前,是否有办法强制下载的文件出现在浏览器中(并防止超时)?调用
flushBuffer()
是否正确?

嗯,它看起来像是用
response.setBufferSize(1000)缩小了输出缓冲区的大小允许成功下载我的压力测试文件。我仍然不知道为什么
response.flushBuffer()
似乎什么都没做,但至少只要我在超时之前生成足够快的数据来填充缓冲区大小,下载就会完成。

客户端是浏览器吗?然后,您可以在客户机中使用非常好的调试工具。当我尝试在新选项卡中加载servlet URL(作为GET请求)并打开调试器的网络窗格时,我可以看到请求一直处于挂起状态,直到第一个块(大文件)或整个文件(对于较小的作业)完成并下载。我不确定我还应该从客户端寻找什么。很明显,在我调用
flushBuffer()
时,服务器没有返回任何内容;e、 g.如果您正在从DB查询生成数据,请获取一个页面,将其写入输出流,然后刷新它。如果您希望
generateFile
花费大量时间,请注意数据库事务超时-您必须将工作拆分为单独的事务。好的。我尝试了一个测试用例,其中我正在编写一个CSV文件,并在每行之后刷新输出流(63行,总共24KB)。这可能会有所帮助,尽管我担心以如此多的块发送响应的服务器负载。是否可以让浏览器仅使用标题和0字节的内容启动下载过程?