考虑以下代码
@RestController
@RequestMapping("/api")
class Controller {
@Autowired
private SomeService service;
@GetMapping("download")
public ResponseEntity<StreamingResponseBody> downloadCsv() {
// service throws some runtime exception
StreamingResponseBody body = outputStream -> service.writeToStream(outputStream);
return ResponseEntity
.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"file.csv\"")
.contentType(MediaType.asMediaType(MediaType.parseMediaType("text/csv")))
.body(body);
}
/* Doesn't work */
@ExceptionHandler(PermissionDeniedException.class)
ResponseEntity<ErrorDetails> handlePermissionDeniedException(PermissionDeniedException e, HttpServletRequest req) {
ErrorDetails details = ....;
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(errorDetails);
}
/* Also doesn't work */
@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "Permission denied")
@ExceptionHandler(PermissionDenied.class)
void handlePermissionDeniedException2() {
}
}
如果从service.writeToStream(outputStream)
抛出了运行时异常,则会调用异常 的@ExceptionHandler
,但是,控制器返回的响应没有一个身体,并将始终具有HttpStatus 500。
如果您不返回ResponseEntity
而不是直接返回StreamingResponseBody
,那么一切都会按预期进行。
/*
@ExceptionHandler works fine with this
*/
@GetMapping("download")
public StreamingResponseBody downloadCsv() {
// service throws some runtime exception
StreamingResponseBody body = outputStream -> service.writeToStream(outputStream);
return body;
}
在将@ExceptionHandler
包裹在StreamingResponseBody
中的同时,有什么方法可以使ResponseEntity
工作吗?
尝试的春季版本:2.3.1.RELEASE,2.3.2.RELEASE Java版本:11