摘要:包含CSV的ResponseEntity<byte[]>
不会作为CSV返回
我正在为下载按钮编写一个控制器,它将使用从另一个依赖项中检索到的数据来生成CSV。
@PostMapping(BASE_ROUTE + "/download")
public ResponseEntity<byte[]> downloadCases(@RequestBody RequestType request, final HttpServletResponse response) throws IOException {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
PrintWriter writer = new PrintWriter(outputStreamWriter, true)) {
String nextPageToken = null;
do {
ServiceResponse serviceResponse = makeServiceCall(request.getParam());
// write a String of comma separated values
writer.println(serviceResponse.getLine());
// eventually null
nextPageToken = serviceResponse.getToken();
} while (nextPageToken != null);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_TYPE, "text/csv")
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"report.csv\"")
.body(outputStream.toByteArray());
}
作为测试,我还尝试将主体设置为.body("Case ID,Assignee".getBytes(StandardCharsets.UTF_8))
。这应该等效于https://stackoverflow.com/a/34508533/10327093
[在两种情况下,我得到的响应看起来都像Base64。示例(缩短的):Q2FzZSBJRCxBc3NpZ25lZQ==
它似乎实际上不是Base64。使用.body(Base64.getDecoder().decode(outputStream.toByteArray()))
给我java.lang.IllegalArgumentException: Illegal base64 character
如果我返回void
并使用IOUtils.write(outputStream.toByteArray(), response.getOutputStream());
将outputStream复制到response.getOutputStream(),则下载的文件正确(CSV)。
但是我想避免直接调用response.getOutputStream()。如果之后收到任何异常,则会在getOutputStream() has already been called for this response
@ExceptionHandler
编辑:Base64解码响应给了我正确的值
System.out.println(new String(Base64.getDecoder().decode("Q2FzZSBJRCxBc3NpZ25lZQ==")));
// Case ID,Assignee
[似乎字节[]在返回ResponseEntity和客户端之间进行了Base64编码(与Postman和浏览器一起尝试。)>
摘要:包含CSV的ResponseEntity
不幸的是,我无法发表评论,因此我将作为答复发布,但这实际上只是一些建议:
TL; DR: