如何在spring mvc rest controller中返回二进制数据而不是base64编码的byte

我想通过spring-mvc-rest控制器返回生成的pdf文件。 这是我目前正在使用的代码的缩短版本:

@RestController @RequestMapping("/x") public class XController { @RequestMapping(value = "/", method = RequestMethod.GET) public ResponseEntity 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(pdf, headers, HttpStatus.OK); } } 

这工作得很好,它只是返回实际的字节数组作为base64编码:(

 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 [...] 

(顺便说一句,响应甚至不包含结束" 🙂

任何提示赞赏!

我使用你的代码创建了这个例子,但是一个非常类似的方法是在我的web应用程序中完成他的工作:

 @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); } 

否则,您可以尝试此答案在新的浏览器选项卡中打开ResponseEntity PDF

问题是由Spring尝试将响应编码为Json引起的。

您的请求可能指定了Accepts = "*/*"并且由于Spring忽略了ResponseEntity的ContentType ,因此发现最佳编码是application/json

最简单的解决方法是在请求映射中添加一个produces ,因此您的代码变为:

 @RestController @RequestMapping(value = "/x", produces = "application/pdf") // <-- Add this public class XController { @RequestMapping(value = "/", method = RequestMethod.GET) public ResponseEntity 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(pdf, headers, HttpStatus.OK); } } 

这是我的代码和工作正常,也许这可以帮助你。

 @RequestMapping(value = "/createReport", method = RequestMethod.POST,produces="application/pdf") @ResponseStatus(value = HttpStatus.OK) public ResponseEntity 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 response = new ResponseEntity(outputReport, headers, HttpStatus.OK); return response; } 

添加生成属性到RequestMapping

 @RequestMapping(path = "/download", produces = "application/pdf")