#java #spring #spring-boot #spring-cloud-feign
#java #spring #весенняя загрузка #spring-cloud-feign
Вопрос:
У меня есть веб-сервис, который вызывает другой WS и возвращает ответ от второго WS. Это выглядит так:
// MyController
public ResponseEntity<Foo> requestFooController(@RequestBody @Valid Bar request) {
return this.myService.requestFooService(request);
}
//MyService
ResponseEntity<Foo> requestFooService(Bar request) {
Buzz improvedRequest = ...
return this.secondWS.secondRequestFoo(improvedRequest);
}
Когда я вызываю API через Postman, я получаю HTTP OK-ответ с пустым телом. Тем не менее, когда я нахожусь в режиме отладки, я вижу, что служба возвращает ResponseEntity
с телом. Заголовки, однако, не потеряны.
Я изменил свой код вот так, и он работает нормально:
// MyController
public ResponseEntity<Foo> requestFooController(@RequestBody @Valid Bar request) {
ResponseEntity<Foo> tmp = this.myService.requestFooService(request);
return ResponseEntity.status(tmp.getStatusCode()).body(tmp.getBody());
}
Теперь через Postman у меня есть ожидаемое тело. Однако я не понимаю поведение. Я подумал, что, возможно, это связано с тем, что тело представляет собой какой-то поток, который можно прочитать один раз или что-то подобное. Но, прочитав исходный код, я не вижу ничего, что могло бы объяснить такое поведение.
Я использую Netflix-stack (поэтому HTTP-вызовы между двумя WS выполняются через Feign
клиент).
Есть идеи, почему я получаю этот результат?
РЕДАКТИРОВАТЬ: Более подробная информация о моей задаче: SpringBoot 1.5.3.RELEASE Feign 2.0.5
Комментарии:
1. Какие версии spring-boot вы используете? Существует ошибка, зависящая от конкретной версии, которая привела к потере имени составного тела, а затем не соответствует параметрам. Вы используете feign, но используете ли вы eureka и zuul в своем стеке Netflix?
2. Да, я использую Zuul и Eureka. Я мог бы попытаться обойти zuul и посмотреть, что произойдет.
Ответ №1:
Существует ошибка, которая приводит к сбою именованного тела составного сообщения HTTP. Признаком этого является то, что вы делаете запрос POST с телом, а Spring-Boot не может сопоставить его с конечной точкой. Исключение, которое я вижу, это:
2019-01-23 15:22:45.046 DEBUG 1639 --- [io-8080-exec-10] .w.s.m.m.a.ServletInvocableHandlerMethod : Failed to resolve argument 3 of type 'org.springframework.web.multipart.MultipartFile'
org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
Zuul выполняет кэширование запроса, чтобы повторить попытку несколько раз. В этом процессе не удается сохранить именованное поле для двоичного тела. Возможно, это сработает, если вы предварите запрос zuul. Поэтому вместо http://myserver.com/myservice/endpoint используйте zuul в пути:http://myserver.com/zuul/myservice/endpoint
Это позволит эффективно избежать сохранения запроса и механизма повторных попыток.
Более подробная информация доступна по этой проблеме в списке ошибок Zuul на GitHub.
Комментарии:
1. Я обновляю до spring-boot 2.1.3, чтобы решить эту проблему в рабочей среде.
2. Спасибо за информацию! Я проверю, есть ли у меня аналогичная проблема в журнале отладки. Я думаю, это будет еще одним аргументом для ускорения обновления 🙂