如何使用servlet从服务器读取pdf文件?

时间:2015-07-04 05:50:48

标签: java jsp pdf servlets

这里我试图使用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();

1 个答案:

答案 0 :(得分:2)

错误在这里:

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,没有人会期望您在Java 6之后的2年仍然存在):

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());

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

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

response.setContentLengthLong(file.length());

另见: