【问题标题】:Java servlet not writing response bytesJava servlet 不写入响应字节
【发布时间】:2020-06-03 05:29:46
【问题描述】:

我有几个 Java servlet (3.x - Tomcat 8) 正在运行,它们生成并返回 PDF 文档。我从来没有遇到过任何问题。我最近编写了一个新的 servlet 来创建和返回一个 PDF 文档,这个新的 servlet 使用的响应代码与其他人使用的完全相同

response.reset();
response.setContentType("application/pdf");
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Content-Disposition","attachment; filename=\""+filename+".pdf\""); 
response.setContentLength(pdfBytes.length);

System.out.println("# Bytes => " + pdfBytes.length);

ServletOutputStream sos = response.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(sos);
bos.write(pdfBytes);
sos.flush();
sos.close();

正如我所说,这与其他的工作正常,但是当我调用新的 servlet 时,它返回 0 字节,即使上面的打印语句具有非零值。

但是,如果我将上面的响应编写代码更改为:

OutputStream os = response.getOutputStream();
os.write(pdfBytes);
os.flush();
os.close();

...它工作正常,返回格式良好的 PDF 文档。为什么会发生这种情况?

【问题讨论】:

  • 不应该 sos.flush();bos.flush(); 等等吗?

标签: java tomcat servlets


【解决方案1】:

您没有刷新BufferedOutputStream - 所以它正在缓冲您的所有数据。你应该刷新那个,而不是ServletOutputStream

但是,如果您只编写一个单字节数组,那么无论如何使用BufferedOutputStream 是没有意义的——而且您无论如何都不需要显式刷新,因为关闭会刷新。所以你只需要:

ServletOutputStream sos = response.getOutputStream();
sos.write(pdfBytes);
// Unclear whether *this* is needed, either.
sos.close();

我个人期望 servlet 容器关闭输出流,但从文档中并不清楚。如果发生异常,是否要关闭它是另一回事...

【讨论】:

  • 成功了!但我不明白。为什么使用相同代码的其他 servlet 工作正常?
  • @RTF:我怀疑他们不是真的。或者它们只是因为正在写入的数据大于缓冲区大小而起作用。你那里的代码肯定坏了。
  • 适合我从一些博客文章中复制和粘贴,并假设它是正确的。看起来我需要进行一些重构,因为我没有为该响应代码创建样板函数!
【解决方案2】:

你真的应该刷新并关闭bos而不是sos

【讨论】:

    猜你喜欢
    • 2013-04-10
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    • 2020-08-04
    相关资源
    最近更新 更多