【问题标题】:How to store a pdf file in postgresql database using servlets?如何使用 servlet 在 postgresql 数据库中存储 pdf 文件?
【发布时间】:2012-05-06 09:32:04
【问题描述】:

我正在从 HTML 上传文件

 <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 对象中获取文件以将其存储在数据库中?

【问题讨论】:

    标签: java file postgresql servlets


    【解决方案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 Commons IO 的一部分;如果您使用 FileUpload,那么您已经拥有它)

    不要忘记将 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();
    

    【讨论】:

    • 考虑使用临时文件或智能缓冲区类,而不是使用内存中的字节[],当它增长到某个特定值时,它知道从内存中的缓冲区切换到临时文件尺寸。此外,虽然它可能对您无关紧要,但 bytea 限制为 1GB。对于更大的文件,将它们存储在数据库之外,只存储路径和校验和。
    • @BalusC 谢谢一百万 :) 这只是完美的答案。我只是有一个小小的疑问。检索时我会得到二进制数据。那么要将其转换为文件并显示该pdf文件,我该怎么办?
    • 使用ResultSet#getBinaryStream()InputStream 从数据库取回它。您想提供它作为下载吗?只需写信给HttpServletResponse#getOutputStream(),并附上一些适当的响应标头,以便浏览器了解如何处理它。你想把它保存为文件吗?只需将其写至new FileOutputStream()。等等。只需根据您的喜好写信给任何OutputStream。另见stackoverflow.com/questions/4614935/…
    • @Balusc 谢谢 :) 帮助很大 :)
    • @BalusC 你说,输入流不合适。每次您需要再次读取 InputStream 时,客户端不会多次重新发送文件。这是什么意思。为什么客户端要多次发送文件?
    【解决方案2】:

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

    【讨论】:

    • 即使我看了你上面提到的代码。我在我的代码中怀疑此语句中的输入流对象“localInputStream” InputStream localInputStream = localFileItem.getInputStream();足以将文件存储在数据库中还是我需要进行任何转换?
    猜你喜欢
    • 2021-12-17
    • 2011-04-16
    • 2012-07-22
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 2016-12-19
    • 1970-01-01
    相关资源
    最近更新 更多