Ответ 1
Spring использует интерфейс HandlerMethodArgumentResolver
, чтобы определить, какие аргументы он передаст вашим методам обработчика. Для параметров, аннотированных с помощью @RequestBody
, он использует класс RequestResponseBodyMethodProcessor
. Этот класс в основном выглядит в виде набора объектов HttpMessageConverter
для одного, который может читать content-type
запроса и может преобразовать его в указанный тип. Если он находит один, он передает тело HttpServletRequest
как InputStream
в объект HttpMessageConverter
.
В этом случае вы, вероятно, найдете работу десериализатора JSON. Это очень вероятно (видя IOException
, который вы получаете), потребляя поток, а затем закрывая его.
Таким образом, действительно, этот способ делать вещи напрямую невозможен.
Одним из решений является создание Filter
, которое обертывает HttpServletRequest
в вашей собственной реализации, которая буферизирует InputStream
, чтобы сделать ее повторно используемой/повторно читаемой столько раз, сколько требуется. Но опять же правила десериализации из тела могут быть приняты Spring, а не то, что вы хотите точно. В этом случае вы можете создать свои собственные Annotation
и HandlerMethodArgumentResolver
, которые затем регистрируются приложением в вашей конфигурации. Затем вы можете точно контролировать, как вещи десериализуются из тела запроса.
Другим решением является объединение как MyObjectDto
, так и messageBody
в один DTO, если это имеет смысл для вашей модели данных (и для процесса десериализации Spring).