2

currently, I am facing a strange behavior in vue.js with axios. My goal is to provide a download link for a pdf which summarizes the user's data. As argument I pass the user's birthdate and a unique id. Using these two parameters I look up the data, generate a pdf using pdfbox and provide the generated pdf via jax-rs. Now, if I download the pdf via axios, the formatting of the pdf completely disappeared. Only the values which where replaced are in the pdf. Everything else is lost. However, if I just use a normal <a href=.. everything works fine. However, the problem with this approach is, that I need to pass the parameters as url query parameters. I would like to use a POST Request and pass the parameters in the body. It seems that the jax-rs endpoint works both with post and get correctly. The problem must be somewhere with axios.

Currently, the endpoint looks like this:

@GET
public Response getApplication(//
        @QueryParam("applicationId") String applicationId,//
        @QueryParam("bd") Long birthTime,//
        @Context HttpServletResponse response)
        throws IOException, URISyntaxException {
    
    Date birthDate = new Date(birthTime);
    
    ApplicantAuthentication authentication = new ApplicantAuthentication(applicationId, birthDate);

    boolean permissionForApplication = permissionUsecase.checkApplicantsPermission(authentication);

    if (!permissionForApplication) {
        return Response//
                .status(Response.Status.UNAUTHORIZED)//
                .build();
    }

    response.setHeader("Content-Disposition", "attachment; filename=hello.pdf");
    response.setContentType("application/pdf");

    ServletOutputStream outStream = response.getOutputStream();

    summaryUsecase.createPdfSummary(applicationId, outStream);

    outStream.flush();

    return Response//
            .status(Response.Status.OK)//
            .build();
}

summaryUsecase.createPdfSummary(applicationId, outStream); calls internally pDDocument.save(outStream); of Appache's PdfBox.

In vue.js, I now use the following approach:

<a :href="pdfUrl">...

computed: {
  pdfUrl: function () {
    return "/rest/summary/pdf?applicationId="+this.applicationId+"&bd="+this.bd;
  }
}

This works. However, I consider this approach as dirty. I need to pass the arguments as query paramets. Furthermore, I do not have the features like proxying during development phase in vue.config.js

I would like an approach like:

<a href="#" @click.prevent="downloadPdf()">...

methods: {
  downloadPdf() {
    RetiremenHomeService.retrieveSummaryPdf(this.applicationId, this.bd).then((response) => {
            const link = document.createElement('a');
            link.href = URL.createObjectURL(new Blob([response.data]));
            link.download = "hello.pdf";
            link.click();
            URL.revokeObjectURL(link.href);
    });
  }
},

using axios in retrieveSummaryPdf-Method:

  static retrieveSummaryPdf(){
     return axios.get(`${RetirementHomeService.serviceUrlPrefix}/summary/pdf`);
  }

If I use static pdfs which are not generated, the desired approach works. It only does not work, when I use PdfBox to generate the pdf in combination with axios.

Does anyone have any clue?

Any kind of help would be appreciated! Thanks.

phe
  • 169
  • 1
  • 8
  • Could you try changing `response.setContentType("application/pdf");` to `response.setContentType("application/octet-stream");`? – Shoejep Nov 07 '20 at 10:17
  • I've just tried that. However, this did not solve the issue. – phe Nov 07 '20 at 11:39
  • Hmm, may be you could edit your question with what `response.data` looks like? You could also pass the type when creating your blob like: `new Blob([response.data], {type: 'application/pdf'})` – Shoejep Nov 09 '20 at 18:42
  • I already tried to add the type, but it didn't change anything. The response.data is a pdf so it is cryptic and will not help. – phe Nov 14 '20 at 13:53

0 Answers0