Файл загружается дважды в Java Jersey API - PullRequest
0 голосов
/ 16 января 2019

Я использую следующий код для загрузки PDF из html с моим рабочим штрафа, но файл загружается дважды, я пытался изменить поведение рендерера, но все еще ничего не получил.

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 голосов
/ 16 января 2019

Вы должны использовать 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();
0 голосов
/ 17 января 2019

Причина дублирования, как упомянуто в Ответ Марка , заключается в том, что вы создаете «временный» файл при создании и записи в FileOutputStream.

Решение: вам не нужно создавать временный файл для обработки загрузки. Вместо создания FileOutputStream, просто используйте StreamingOutput и передайте StreamingOutput OutputStream методу ITextRenderer#createPDF(OutputStream).

@GET
@Produces("application/pdf")
public Response getResumePdf(@PathParam("userId") String userId) {

    StreamingOutput entity = new StreamingOutput() {
        @Override
        public void write(OutputStream output) {
            try {
                ITextRenderer renderer = new ITextRenderer();
                String yourXhtmlContentAsString = "<h1>hi </h1>";
                renderer.setDocumentFromString(yourXhtmlContentAsString);
                renderer.layout();
                renderer.createPDF(output);
                output.flush();
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    return Response.ok(entity)
         .header(...)
         .build();
}
0 голосов
/ 16 января 2019

выпуск

В вашем коде вы генерируете файл, который затем будет обслуживаться вашим API. Этот файл создается с new java.io.FileOutputStream(filePath) и называется Resume2019-01-16.pdf, расположенный в папке Downloads.

Поскольку вы используете свой API локально, при переходе к конечной точке браузер загрузит файл, который вы обслуживаете, в вашу папку Downloads. Поскольку Resume2019-01-16.pdf уже существует, браузер назовет его Resume2019-01-16 (1).pdf.

Следовательно, похоже, что загружаются два файла, но один генерируется вашим кодом, а другой фактически загружен.

Fix

Измените папку для файлов, которые вы обслуживаете, и в вашем Downloads появятся только фактически загруженные файлы, например:

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

В качестве альтернативы используйте некоторый метод для сохранения вашего файла в памяти, вместо создания физического файла, и используйте его вместо этого.

...