Reputation: 175
I want to return a generated pdf file via spring-mvc-rest controller. This is a shortened version of the code I'm currently using:
@RestController
@RequestMapping("/x")
public class XController {
@RequestMapping(value = "/", method = RequestMethod.GET)
public ResponseEntity<byte[]> find() throws IOException {
byte[] pdf = createPdf();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(new MediaType("application", "pdf"));
headers.setContentDispositionFormData("attachment", "x.pdf");
headers.setContentLength(pdf.length);
return new ResponseEntity<byte[]>(pdf, headers, HttpStatus.OK);
}
}
This works almost fine, it just to return the actual byte array as base64 encoded :(
curl -i 'http://127.0.0.1:8080/app/x'
Server: Apache-Coyote/1.1
Content-Disposition: form-data; name="attachment"; filename=x.pdf"
Content-Type: application/pdf
Content-Length: 138654
Date: Fri, 08 Jan 2016 11:25:38 GMT
"JVBERi0xLjYNJeLjz9MNCjMyNCAwIG9iag [...]
(btw. the response doesn't even contain a closing "
:)
Any hints appreciated!
Upvotes: 14
Views: 31095
Reputation: 49677
The problem is caused by Spring trying to encode the response as Json.
Your request probably specifies Accepts = "*/*"
and since Spring ignores the ResponseEntity's ContentType
, the best encoding is found to be application/json
.
The simplest fix to this is to add a produces
to your request mapping, so your code becomes:
@RestController
@RequestMapping(value = "/x",
produces = "application/pdf") // <-- Add this
public class XController {
@RequestMapping(value = "/", method = RequestMethod.GET)
public ResponseEntity<byte[]> find() throws IOException {
byte[] pdf = createPdf();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PDF);
headers.setContentDispositionFormData("attachment", "x.pdf");
headers.setContentLength(pdf.length);
return new ResponseEntity<byte[]>(pdf, headers, HttpStatus.OK);
}
}
Upvotes: 11
Reputation: 7871
The answer from Rasmus Faber is very close.
In my case: I want to view a PDF generated by spring. I don't want to download it.
But I get every time the base64 encoded string, instead of my byte[]
.
I found out that I get the base64-string only in Firefox. So I switched to chrome, where the answer from Rasmus working fine.
Now, it works in Firefox too. But I can't say why (I changed nothing). I guess that something was cached.
For more information, this might help Incorrect content type for PDF file with Firefox
My working code with streams:
@GetMapping(path = "/demo/pdf", produces = "application/pdf")
public StreamingResponseBody getPdf(final HttpServletResponse response) {
response.setContentType("application/pdf");
response.setHeader("cache-control","must-revalidate, post-check=0, pre-check=0");
response.setHeader("Content-Disposition", "inline; filename=aCleverFileName.pdf");
return outputStream -> this.pdfService.createPdf(outputStream);
}
Upvotes: 0
Reputation: 11
Add produces property to RequestMapping
:
@RequestMapping(path = "/download", produces = "application/pdf")
Upvotes: 1
Reputation: 483
This is my code and work fine, maybe this would can help you.
@RequestMapping(value = "/createReport", method = RequestMethod.POST,produces="application/pdf")
@ResponseStatus(value = HttpStatus.OK)
public ResponseEntity<byte[]> createReport(@RequestBody ReporteDTO reporteDTO) {
byte[] outputReport = null;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/pdf"));
headers.setContentDispositionFormData("inline", "archivo.pdf");
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
outputReport = getFilePdf();
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(outputReport, headers, HttpStatus.OK);
return response;
}
Upvotes: 2
Reputation: 409
I created the example using your code, but a very similar method is doing his job in my web application:
@RequestMapping(value = "/", method = RequestMethod.GET)
public void downloadFile(HttpServletResponse response,
HttpServletRequest request) throws IOException
{
byte[] pdf = createPdf();
response.setContentType("application/x-download");
response.setHeader("Content-Disposition", "attachment; filename=foo.pdf");
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.getOutputStream().write(pdf);
}
Else you can try this answer Open ResponseEntity PDF in new browser tab
Upvotes: 7