【问题标题】:how to read pdf file from server using servlet?如何使用 servlet 从服务器读取 pdf 文件?
【发布时间】:2015-09-21 22:05:07
【问题描述】:

这里我正在尝试使用 java servlet 从服务器读取 pdf 文件。下面的代码我正在获取文件路径,如果文件存在,然后尝试读取文件,但是文件没有打开?

 String filePath = dirName;
            String fileName = si + "_" + dnldFilename;
            FileInputStream fileToDownload = new FileInputStream(filePath.concat(fileName);
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            response.setContentLength(fileToDownload.available());
            int c;
            while ((c = fileToDownload.read()) != -1) {
                response.getOutputStream().write(c);
            }
            response.getOutputStream().flush();
            response.getOutputStream().close();
            fileToDownload.close();

【问题讨论】:

  • 您遇到异常了吗?如果有呢?
  • 您没有将文件名附加到 filePath,至少从上面的代码中。
  • 上面的代码甚至无法编译。发布真实代码,并准确说明问题所在。发布您获得的完整异常堆栈跟踪。告诉你预期会发生什么,以及会发生什么。

标签: java jsp pdf servlets


【解决方案1】:

错误就在这里:

response.setContentLength(fileToDownload.available());

InputStream#available() 不会按照您 (and the average Java starter) 的想法行事。它不返回响应标头所代表的总内容长度。它返回可用于读取的字节量,而不会阻塞所有其他线程(即当前已放入硬件缓冲区的字节)。如果这小于实际文件大小,则客户端可能会简单地停止读取响应的其余部分。换句话说,客户只得到了 PDF 文件的一部分,因为您告诉客户所需的部分正好是给定的长度。

你需要构造一个普通的java.io.File,并通过File#length()获取文件大小。

这是一个完整的重写,也进一步减少了遗留的 Java IO 样板。这假设您至少使用 Java 7(因为 Java 6 自 2013 年以来就是 EOL,所以没有人会期望您在日期后 2 年仍然使用 Java 6):

File file = new File(filePath, fileName);
response.setHeader("Content-Type", getServletContext().getMimeType(file.getName()));
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
Files.copy(file.toPath(), response.getOutputStream());

就是这样。请注意,上面的代码 sn-p 也可以通过这种方式重用于所有其他类型的文件。您可以通过web.xml 中的<mime-mapping> 条目管理未知内容类型。

另外请注意,我将内容长度转换为字符串,因为 setContentLength() 只接受 intFile#length() 返回 long,如果文件大于 2GB,则会失败。如果您已经使用 Servlet 3.1(Tomcat 8 等),请使用新的 setContentLengthLong() 方法。

response.setContentLengthLong(file.length());

另见:

【讨论】:

    最近更新 更多