具有ResponseEntity <StreamingResponseBody>的Spring Boot @ExceptionHandler不起作用

时间:2020-07-29 00:10:58

标签: java spring spring-boot

考虑以下代码

@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

0 个答案:

没有答案