Spring Cloud Gateway не возвращает правильный код ответа, предоставленный службой Downstream (для загрузки файла)

У меня есть простой сервис для загрузки файлов. Образец кода

@RestController
@RequestMapping("/file")
public class FileController {

    @PostMapping("/upload")
    public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file,
        @RequestParam(value = "delay", required = false, defaultValue = "0") int delay) throws Exception {

        System.out.println(String.join(System.getProperty("line.separator"),
            "File Name => " + file.getOriginalFilename(),
            "File Size => " + file.getSize() + "bytes",
            "File Content Type => " + file.getContentType()));

        TimeUnit.MILLISECONDS.sleep(delay);

        return ResponseEntity.ok(file.getName() + " uploaded");
    }

}

и CustomExceptionHandler, который возвращает BAD_REQUEST, если есть MultipartException:

@Configuration
@ControllerAdvice
public class CustomExceptionHandler {
    @ExceptionHandler(MultipartException.class)
    public ResponseEntity<String> handleMultipartException(MultipartException ex) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage());
    }
}

Максимальный размер файла application.yml составляет 10 МБ:

spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB

Если я загружаю большой файл, это дает мне статус 400, как ожидалось  Обслуживание файлов 400

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

введите здесь описание изображения

и журналы показывают следующее:

2019-11-08 00:36:10.797 ERROR 21904 --- [ctor-http-nio-2] a.w.r.e.AbstractErrorWebExceptionHandler : [86e57f7e] 500 Server Error for HTTP POST "/product-service/file/upload"

reactor.netty.http.client.PrematureCloseException: Connection has been closed BEFORE response, while sending request body

Обратите внимание, что шлюз настроен на прием файлов большого размера с RequestSize фильтром, установленным глобально, чтобы занимать больше 10 МБ.

Как я могу получить тот же код ответа, что и нижестоящая служба?

Кроме того, я проверяю с помощью традиционного зуула и тоже получаю 500 ошибку.

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

Пример кода spring-cloud-gateway / product-service / eureka - https://github.com/dhananjay12/spring-cloud/tree/master/spring-routing


person Dhananjay    schedule 07.11.2019    source источник


Ответы (1)


Можете ли вы попробовать пройти без ограничения объема файла напрямую, чтобы не проходить через путь? попробуйте значение -1 для свойств:

файл свойств MS, куда вы хотите загрузить файл

spring.servlet.multipart.max-file-size =-1

spring.servlet.multipart.max-request-size =-1

Если все в порядке, это может вызвать проблему с размером сокета ленты прокси-сервера zuul, для этого типа ситуации указаны следующие свойства:

Файл свойств путевки:

ribbon.eager-load.enabled=true
hystrix.command.default.execution.timeout.enabled=false
hystrix.command.default.execution.isolation.strategy=THREAD

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3999996
ribbon.ConnectTimeout=999999
ribbon.ReadTimeout=999999
ribbon.SocketTimeout=999999
zuul.host.socket-timeout-millis=999999
zuul.host.connect-timeout-millis=999999
zuul.sensitiveHeaders=Cookie,Set-Cookie
person Omar Amaoun    schedule 02.04.2020