我在 Spring 中有一个 rest API,用于生成和下载 PDF 文件。 Controller 定义如下 -
@RequestMapping(
value = "/foo/bar/pdf",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@ResponseBody
@Nullable
public ByteArrayResource downloadPdf(@RequestParam int userId) {
byte[] result = null;
ByteArrayResource byteArrayResource = null;
result = service.generatePdf(userId);
if (result != null) {
byteArrayResource = new ByteArrayResource(result);
}
return byteArrayResource;
}
我使用 Jackson 来处理 JSON,并有一个异常处理程序 ControllerAdvice。问题是当此 API 生成异常并且我返回自定义异常类(包含消息和一个附加字段)时。
正如我已经指定的produces = MediaType.APPLICATION_OCTET_STREAM_VALUE
Spring 也尝试将此自定义类转换为八位字节流,但失败并生成 HttpMediaTypeNotAcceptableException: Could not find acceptable代表
。
我在 this 上尝试了解决方案Stackoverflow 问题,特别是 this answer但它仍然失败。此解决方案以及其他更改建议从 @RequestMapping
中删除 produces
部分,但是当我调试到 AbstractMessageConverterMethodProcessor.getProducibleMediaTypes
时,它只检测到 application/json 作为可用的响应媒体类型。
长话短说 如何让此 API 在成功时返回文件并在出错时正确返回自定义异常类的 JSON 表示形式。
最佳答案
我用类似的代码遇到了同样的问题。我刚刚从我的 @PostMapping
中删除了 produces
属性,我能够返回文件或 json(当 api 有一些错误时):
@Override
@PostMapping
public ResponseEntity<InputStreamResource> generate(
@PathVariable long id
) {
Result result = service.find(id);
return ResponseEntity
.ok()
.cacheControl(CacheControl.noCache())
.contentLength(result.getSize())
.contentType(MediaType.parseMediaType(MediaType.APPLICATION_PDF_VALUE))
.body(new InputStreamResource(result.getFile()));
}
当发生某些错误时,我有一个@ExceptionHandler
来处理:
@ExceptionHandler
public ResponseEntity<ApiErrorResponse> handleApiException(ApiException ex) {
ApiErrorResponse error = new ApiErrorResponse(ex);
return new ResponseEntity<>(error, ex.getHttpStatus());
}
关于java - Spring - 无法为返回 ByteArrayResource 的 API 发送错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41058642/