Как завершить работу StreamingResponseBody, если произошло исключение (Spring)

У меня есть конечная точка Spring REST, которая загружает zip-архив с помощью StreamingResponseBody:

      @GetMapping("/zip/download")
public ResponseEntity<StreamingResponseBody> downloadZip(
        @RequestParam String id) {
  return zipService.downloadZip(id);
}

При скачивании больших файлов есть вероятность исключения, а если исключение происходит, то браузер ничего об этом не знает, а я просто получаю неполноценный, битый zip архив, а пользователь об этом ничего не знает .

Как сообщить браузеру, что произошла ошибка, чтобы он отображал файл как ошибку при загрузке? Я ожидаю, что браузер напишет в списке загрузок, что произошла ошибка, например:screenshot. Но загрузка отображается как успешно завершенная, и я получаю неправильный файл.

Я попытался написать ExceptionHandler следующим образом:

      @ExceptionHandler(ZipArchiveDownloadException.class)
ResponseEntity<ApiError> handleZipArchiveDownloadException(ZipArchiveDownloadException e, HttpServletRequest request, HttpServletResponse response) {
  ApiError apiError = ApiError.of("Internal Server Error", e.getLocalizedMessage());
  response.setContentType("application/json");
  return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
          .contentType(MediaType.APPLICATION_JSON)
          .body(apiError);
}

Но это не помогло, а также я получаю исключения:

      org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class com.test.exception..ApiError] with preset Content-Type 'application/zip'
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:309) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:219) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:123) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:407) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:61) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:141) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:80) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1300) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1111) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1057) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
      2022-11-25 10:32:56.676 ERROR 43440 --- [0.0-9001-exec-2] s.e.ErrorMvcAutoConfiguration$StaticView : Cannot render error page for request [/zip/download] and exception [] as the response has already been committed. As a result, the response may have the wrong status code.

Что мне нужно сделать, чтобы браузер распознал ошибку и отобразил файл как ошибку загрузки?

0 ответов

Другие вопросы по тегам