文件在Java Jersey API中下载了两次

时间:2019-01-16 11:23:37

标签: java pdf jersey itext html-to-pdf

我正在使用以下代码从html下载PDF包含我的工作正常,但是文件被下载了两次,我试图修改渲染器行为,但仍然没有任何内容。

public Response downloadResumePdf(@PathParam("userId") String userId) throws IOException, DocumentException {
     String homePath = System.getProperty("user.home");
        String filePath = homePath + "/Downloads/Resume" + LocalDateTime.now().toLocalDate() + ".pdf";
        org.xhtmlrenderer.pdf.ITextRenderer renderer = new ITextRenderer();
        String yourXhtmlContentAsString = "<h1>hi </h1>";
        renderer.setDocumentFromString(yourXhtmlContentAsString);
        renderer.layout();
        java.io.FileOutputStream fos = new java.io.FileOutputStream(filePath);
        renderer.createPDF(fos);
        fos.close();
        File file = new File(filePath);
        return Response
          .ok((Object) file)
          .header("Content-Disposition", "attachment; filename=\"Resume" + LocalDateTime.now().toLocalDate() + ".pdf\"")
          .build();

3 个答案:

答案 0 :(得分:1)

问题

在您的代码中,您正在生成一个文件,然后将其提供给您的API。该文件是用new java.io.FileOutputStream(filePath)创建的,位于Resume2019-01-16.pdf文件夹中的名为Downloads

由于您是在本地运行API,因此当您转到端点时,浏览器会将您提供的文件下载到Downloads文件夹中。由于Resume2019-01-16.pdf已经存在,浏览器将其命名为Resume2019-01-16 (1).pdf

因此,似乎正在下载两个文件,但是其中一个是由您的代码生成的,而另一个实际上是 下载的。

修复

更改正在提供的文件的文件夹,只有实际下载的文件才会出现在Downloads中,例如:

String filePath = homePath + "/Documents/Resume" + LocalDateTime.now().toLocalDate() + ".pdf";

或者使用某种方法将文件存储在内存中,而不是创建物理文件并提供服务。

答案 1 :(得分:1)

Mark's answer中所述,重复的原因是因为您在创建和写入FileOutputStream时正在创建“临时”文件。

解决方案:您无需创建临时文件即可处理下载。无需创建FileOutputStream,只需使用StreamingOutput并将StreamingOutput的{​​{1}}传递给OutputStream方法即可。

ITextRenderer#createPDF(OutputStream)

答案 2 :(得分:0)

您使用StreamingOutput代替使用File。

String homePath = System.getProperty("user.home");
    String filePath = homePath + "/Downloads/Resume" + LocalDateTime.now().toLocalDate() + ".pdf";

    org.xhtmlrenderer.pdf.ITextRenderer renderer = new ITextRenderer();

    String yourXhtmlContentAsString = "<h1>hi </h1>";
    renderer.setDocumentFromString(yourXhtmlContentAsString);
    renderer.layout();

    java.io.FileOutputStream fos = new java.io.FileOutputStream(filePath);
    renderer.createPDF(fos);
    //fos.close();
    final File file = new File(filePath);

    StreamingOutput fileStream =  new StreamingOutput()
    {
        @Override
        public void write(java.io.OutputStream output) throws IOException, WebApplicationException
        {
            try
            {

                byte[] data = Files.readAllBytes(file.toPath());
                output.write(data);
                output.flush();
            }
            catch (Exception e)
            {
                throw new WebApplicationException("File Not Found. !!");
            }
        }
    };

   return Response
       .ok( fileStream, MediaType.APPLICATION_OCTET_STREAM)
       .header("Content-Disposition", "attachment; filename=\"Resume" + LocalDateTime.now().toLocalDate() + ".pdf\"")
       .build();