2012-04-25 39 views
0

我从HTML
上传文件如何使用servlet将pdf文件存储在postgresql数据库中?

<center><form action="pdf" method="post" enctype="multipart/form-data"> 
     <b>Upload Certificate</b> 
     <input type="file" name="file"/></center> 
     <center> <input type="submit" /></center> 
</form> 

在提交表单,PDF格式的Servlet被调用。在servlet内部,解析请求对象并使用InputStream读取文件(pdf),如下面的代码所示。

protected void doPost(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse) 
    throws ServletException, IOException 
    { 
    try 
    { 
     List localList = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(paramHttpServletRequest); 
     for (FileItem localFileItem : localList) 
     { 
     String str1 = localFileItem.getFieldName(); 
     String str2 = FilenameUtils.getName(localFileItem.getName()); 
     System.out.println("fieldname:" + str1); 
     System.out.println("filename:" + str2); 
     InputStream localInputStream = localFileItem.getInputStream(); 
     try 
     { 
      PdfReader localPdfReader = new PdfReader(localInputStream); 
      paramHttpServletResponse.sendRedirect("takedetails.jsp"); 
     } 
     catch (InvalidPdfException localInvalidPdfException) 
     { 
      paramHttpServletResponse.sendRedirect("upload.jsp"); 
     } 

     } 

    } 
    catch (FileUploadException localFileUploadException) 
    { 
     throw new ServletException("Cannot parse multipart request.", localFileUploadException); 
    } 
    } 

如您所见,我使用InputStream对象检查文件格式为pdf。

现在我想把这个pdf文件保存到postgresql数据库。我应该在postgresql中使用哪些字段,以及如何从InputStream对象中获取文件以将其存储在数据库中?

回答

1

目前尚不清楚您使用的持久性API。 JDBC? JPA?好醇'休眠?我将假设JDBC。在JDBC中,可以使用PreparedStatement#setBinaryStream()InputStream存储在数据库中,或使用PreparedStatement#setBytes()byte[]存储在数据库中。无论哪种方式,在PostgreSQL中你都需要一个bytea列。

由于您首先通过PdfReader验证上传的文件,因此InputStream是不合适的。它可以只读一次。每当您需要再次阅读InputStream时,客户端不会重复发送文件多次。您需要首先将InputStream复制到byte[]

ByteArrayOutputStream output = new ByteArrayOutputStream(); 
IOUtils.copy(localFileItem.getInputStream(), output); 
byte[] filecontent = output.toByteArray(); 

IOUtils就是Apache下议院IO的一部分;如果你使用的文件上传,那么你已经拥有它)

不要忘记更改iText的使用byte[]代替:

PdfReader localPdfReader = new PdfReader(filecontent); 

你的iText通过验证后,您可以在如下存储在使用JDBC的PostgreSQL bytea柱:

statement = connection.prepareStatement("INSERT INTO files (name, content) VALUES (?, ?)"); 
statement.setString(1, filename); 
statement.setBytes(2, filecontent); 
statement.executeUpdate(); 
+0

而不是使用内存中的字节[],请考虑使用临时文件或智能缓冲区类,该缓冲区类在知道从内存缓冲区切换到临时文件时会超过特定大小。另外,虽然它可能对你无关紧要,但是bytea限制为1GB。对于更大的文件,将它们存储在数据库之外并只存储路径和校验和。 – 2012-04-25 21:54:47

+0

@BalusC感谢百万:)这只是一个完美的答案。我刚刚得到了一个小小的最终怀疑。虽然检索我会得到二进制数据。因此,要将其转换为文件并显示该pdf文件,我该怎么办? – suraj 2012-04-26 04:25:10

+0

使用'ResultSet#getBinaryStream()'将它从数据库中取回为'InputStream'。你想提供它作为下载?只需在一些适当的响应头文件中写入'HttpServletResponse#getOutputStream()',以便浏览器理解如何处理它。你想将它保存为文件吗?只需将它写入'新的FileOutputStream()'。等等。只需写入任何“OutputStream”即可。另请参阅http://stackoverflow.com/questions/4614935/how-to-display-a-pdf-file-in-jsp-using-servlet/4615155#4615155 – BalusC 2012-04-26 04:28:47

1

forum中有类似的问题。 它使用图像而不是pdf。但程序可能是相同的。 将流保存到文件并将其存储到数据库。 检查出来。也许可以帮助你。

For example, suppose you have a table containing the file name of an image and you also want to store the image in a bytea column: 

CREATE TABLE images (imgname text, img bytea); 

To insert an image, you would use: 

File file = new File("myimage.gif"); 
FileInputStream fis = new FileInputStream(file); 
PreparedStatement ps = conn.prepareStatement("INSERT INTO images VALUES (?, ?)"); 
ps.setString(1, file.getName()); 
ps.setBinaryStream(2, fis, file.length()); 
ps.executeUpdate(); 
ps.close(); 
fis.close(); 
+0

即使我看了一下上面提到的代码。我在我的代码中怀疑输入流对象“localInputStream”是否在这个语句中InputStream localInputStream = localFileItem.getInputStream();足以将文件存储在数据库中或者是否需要执行任何转换? – suraj 2012-04-25 17:45:00

相关问题