1

I have a problem using iTextPdf in a WEB Context application.

I have a web servlet that downloads a PDF after I have edited it in runtime.

If I call my method that prepare the PDF in a NON-WEB context application, the PDF is created perfectly and it opens without any problem.

But in a WEB-Context application, the file is created, but when I make the download from my test page it's corrupted: when I open the downloaded file, it's without images and appears an error message about a font that is not found.

If I open the "clean" file and the "corrupted" file with a text editor, they have the same number of lines, but in fact the content appears different.

So I suspect that the problem is the rendering of the content-type in the web response, or something similar.

I have followed this documentation: http://developers.itextpdf.com/examples/itext-action-second-edition/chapter-9

This is the Spring MVC controller implementation:

@RequestMapping(path = "/downloadPDF", method = RequestMethod.GET)
public void downloadPDF(HttpServletResponse response){
    try{
        response.setContentType("application/pdf;charset=UTF-8");       
        ByteArrayOutputStream baos = myPDFHandler.getPdf('filetest.pdf');
        OutputStream outputStream = response.getOutputStream();
        baos.writeTo(outputStream);
        outputStream.flush();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

These are the response headers:

Response Headers

view source
Cache-Control:no-store
Cache-Control:no-cache
Content-Type:application/pdf;charset=UTF-8
Date:Tue, 24 May 2016 10:20:56 GMT
Expires:Thu, 01 Jan 1970 00:00:00 GMT
Pragma:no-cache
Server:Apache-Coyote/1.1
Strict-Transport-Security:max-age=31536000 ; includeSubDomains
Transfer-Encoding:chunked
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block

The problem is not in " myPDFHandler.getPdf" method, because in a NON-WEB context it works perfectly.

Any idea? Thanks.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Alessandro C
  • 3,310
  • 9
  • 46
  • 82
  • 1
    is it for sure that the file is `UTF-8` encoded ? – Bond - Java Bond May 24 '16 at 11:06
  • I tried with charset=UTF-8 and without it, but the result is the same. When I try in NON-WEB context I don't need to specify it... – Alessandro C May 24 '16 at 11:26
  • `charset=UTF-8` is wrong there nonetheless. That been said, can you share the PDF, once as the Browser receives it and once as stored on the server? – mkl May 24 '16 at 11:30
  • @Alessandro try with return type of `ResponseEntity`. You can use [this](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/ResponseEntity.html#ResponseEntity-T-org.springframework.util.MultiValueMap-org.springframework.http.HttpStatus-) constructor to specify the relevant response details (argument named body will be of type `byte[]`) – Bond - Java Bond May 24 '16 at 11:32
  • @Bond Thanks for the suggest. I'have tried but the problem is that I have an Angular Spring Data Rest application that expects as return a JSON, not a byte array... – Alessandro C May 24 '16 at 12:44

1 Answers1

1

I have found the solution.

The problem was the return type of the @Controller, changing void to @ResponseBody byte[] worked.

I also removed "charset=UTF-8" and I have added the header "content-disposition".

@RequestMapping(path = "/downloadPDF", method = RequestMethod.GET)
public @ResponseBody byte[] downloadPDF(HttpServletResponse response){
    try{
        response.setContentType("application/pdf"); 
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=somefile.pdf");     
        ByteArrayOutputStream baos = myPDFHandler.getPdf('filetest.pdf');
        return baos.toByteArray();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
Alessandro C
  • 3,310
  • 9
  • 46
  • 82