Я ничего не знаю о Spring, но я могу, по крайней мере, сказать, что тело запроса POST может быть прочитано только один раз . Это именно те данные, которые клиент отправил на сервер. Клиент не будет отправлять его повторно несколько раз, когда это потребуется серверу несколько раз.
Я предполагаю, что Spring уже прочитал тело запроса, чтобы проанализировать вложенную строку запроса и получить параметры запроса перед входом в метод контроллера Spring. Это можно сделать под прикрытием Spring с request.getParameter()
и суппортами. В Servlet API, после вызова этого метода, request.getInputStream()
и request.getReader()
впоследствии ничего не вернут. Просто потому, что тело запроса уже прочитано, чтобы вернуть параметры. Это также упоминается в javadoc getParameter()
.
Если данные параметров были отправлены в теле запроса, например, при запросе HTTP POST, то чтение тела напрямую через getInputStream()
или getReader()
может помешать выполнению этого метода.
Лучше всего создать фильтр , который будет делать копию тела запроса до того, как Spring выполнит свою работу, а затем поместить фильтр перед контроллером Spring. Создание копии тела запроса возможно с помощью HttpServletRequestWrapper
, в котором вы переопределяете методы getInputStream()
и getReader()
, чтобы сначала прочитать тело запроса в ByteArrayInputStream
и / или CharArrayReader
чтобы у вас была локальная копия, а затем вернуть ее. Ссылка на HttpServletRequestWrapper
может быть сохранена как атрибут запроса, так что вы можете получить его как атрибут запроса в контроллере Spring и, наконец, получить копию тела запроса.