java 如何在spring mvc rest控制器中返回二进制数据而不是base64编码的字节[]

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34676037/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 23:11:42  来源:igfitidea点击:

How to return binary data instead of base64 encoded byte[] in spring mvc rest controller

javaspringspring-mvc

提问by J. Doe

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:

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

@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 :(

这几乎可以正常工作,它只是将实际字节数组返回为 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 [...]

(btw. the response doesn't even contain a closing ":)

(顺便说一句。响应甚至不包含结束语":)

Any hints appreciated!

任何提示表示赞赏!

采纳答案by ElPysCampeador

I created the example using your code, but a very similar method is doing his job in my web application:

我使用您的代码创建了示例,但在我的 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);
}

Else you can try this answer Open ResponseEntity PDF in new browser tab

否则你可以试试这个答案Open ResponseEntity PDF in new browser tab

回答by Rasmus Faber

The problem is caused by Spring trying to encode the response as Json.

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

Your request probably specifies Accepts = "*/*"and since Spring ignores the ResponseEntity's ContentType, the best encoding is found to be application/json.

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

The simplest fix to this is to add a producesto your request mapping, so your code becomes:

对此最简单的解决方法是将 a 添加produces到您的请求映射中,因此您的代码变为:

@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(new MediaType("application", "pdf"));
        headers.setContentDispositionFormData("attachment", "x.pdf");
        headers.setContentLength(pdf.length);
        return new ResponseEntity<byte[]>(pdf, headers, HttpStatus.OK);
    }
}

回答by jose rivera

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

回答by Donald John

Add produces property to RequestMapping:

将生产属性添加到RequestMapping

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