Всем привет, мы снова встретились, я ваш друг Цюаньчжаньцзюнь.
Совет: рекомендуется прочитать исходный код основной логики @RequestBody и шесть важных выводов позже!Первая половина этой статьи содержит некоторые основные сведения. Эти сведения являются общеизвестными и могут быть пропущены.
заявление:Эта статья основана наSpringBoot,Проведены демонстрационные инструкции.
@RequestBody в основном используется для получения данных в строке json, передаваемой из внешнего интерфейса в серверный (данные в теле запроса, и наиболее часто используемым телом запроса для передачи параметров, несомненно, является запрос POST, поэтому при использовании @RequestBody); для получения данных, обычно отправляемых с помощью POST. В одном и том же методе получения на серверной стороне одновременно могут использоваться @RequestBody и @RequestParam(). Может быть не более одного @RequestBody, но может быть несколько @RequestParam().
Примечание. Запрос имеет только один RequestBody; запрос может иметь несколько RequestParams.
Примечание. При одновременном использовании @RequestParam() и @RequestBody параметры, указанные в @RequestParam(), могут быть обычными элементами, Массивы, коллекции, объекты и т. д. (т. е. когда @RequestBody и @RequestParam() можно использовать одновременно, исходный SpringMVC получает Механизм параметров остается неизменным, за исключением того, что RequestBody получает данные в теле запроса, а RequestParam получает значение ключа; Параметры внутри, поэтому он будет обработан аспектом и может быть получен обычными элементами, массивами, коллекциями, объектами и т.д.). То есть: если параметры помещаются в тело запроса и фону передается application/json, то для его получения фон должен использовать @RequestBody; Если он не помещен в тело запроса, то, когда фон получает параметры, переданные спереди, он должен использовать @RequestParam для их получения, или Тогда его можно будет получить, ничего не записывая перед формальными параметрами.
Примечание. Если перед параметром записан @RequestParam(xxx), то интерфейс должен иметь соответствующее имя xxx (независимо от того, имеет ли оно значение, его, конечно, можно передать Отрегулируйте необходимость его передачи, установив обязательный атрибут аннотации). Если имя xxx отсутствует, запрос выдаст ошибку и сообщит 400.
Примечание. Если @RequestParam(xxx) не записан перед параметром, внешний интерфейс может иметь соответствующее имя xxx, если есть имя xxx. Если да, то оно будет автоматически соответствовать; если нет, то запрос будет отправлен правильно. Дополнительное примечание: это отличается от случая, когда feign использует службы; если перед параметром ничего не записано, по умолчанию будет установлено значение. @RequestBody.
Если внутренний параметр является объектом и параметр изменен с помощью @RequestBody, то когда внешний интерфейс передает параметр json, он должен соответствовать следующим требованиям:
Примечание. Что касается использования @RequestParam(), я не буду подробно объяснять это здесь. Подробности см. в соответствующих главах «Заметки о развитии программиста (1)».
Сначала дайте два класса сущностей, которые будут использоваться позже.
Класс пользовательской сущности:
Класс сущности команды:
@RequestBody напрямую получает данные json, передаваемые из внешнего интерфейса в виде строки:
Контроллер, соответствующий бэкэнду:
Проверьте с помощью PostMan:
@RequestBody получает данные json, переданные из внешнего интерфейса, в виде простого объекта:
Контроллер, соответствующий бэкэнду:
Проверьте с помощью PostMan:
@RequestBody получает данные json, переданные из внешнего интерфейса, как сложный объект:
Контроллер, соответствующий бэкэнду:
Проверьте с помощью PostMan:
@RequestBody используется с простым @RequestParam():
Контроллер, соответствующий бэкэнду:
Проверьте с помощью PostMan:
@RequestBody используется вместе со сложным @RequestParam():
Контроллер, соответствующий бэкэнду:
Проверьте с помощью PostMan:
@RequestBody получает данные json в теле запроса, получает данные в URL-адресе без аннотаций и собирает их в объект:
Контроллер, соответствующий бэкэнду:
Проверьте с помощью PostMan:
Примечание. Если @RequestParam() указан перед параметрами внутреннего метода, то у внешнего интерфейса должны быть соответствующие поля (конечно, вы можете установить Обязательный атрибут аннотации используется для настройки того, должна ли она быть передана), в противном случае будет сообщено об ошибке, если перед параметром нет такой аннотации, интерфейсная часть может передать ее, или Чтобы не передать это дальше, например:
На приведенном выше рисунке, если мы не указываем токен в переданном параметре, запрос может быть отправлен в обычном режиме, но токен имеет значение null; если @RequestParam("token") указан перед токеном String, то внешний интерфейс должен иметь значение null; токен-ключ при запросе. Только тогда вы сможете войти нормально, иначе будет выдано сообщение об ошибке 400.
Заявление. В зависимости от разных типов контента и других ситуаций Spring-MVC будет использовать разные реализации HttpMessageConverter для преобразования и анализа информации. Наиболее часто используется следующий вариант: внешний интерфейс использует Content-Type как application/json и передает строковые данные json, внутренний интерфейс использует @RequestBody; Как модель получает данные.
Обзор общего процесса анализа данных json: Http передает информацию тела запроса, которая в конечном итоге будет инкапсулирована в com.fasterxml.jackson.core.json.UTF8StreamJsonParser (подсказка: Spring использует FeatureEncodingFilter для установки кодировки по умолчанию UTF-8), а затем публикуется публично. class BeanDeserializer extends BeanDeserializerBase implements java.io.Serializable, через public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) выдает исключение IOException.。
Предположим, что строка json, передаваемая через интерфейс, выглядит следующим образом: {"имя1":"Дэн Салливан","возраст":123,"мот":"Я маленькая птичка~"} Внутренняя модель имеет только атрибуты name и age, а также соответствующие методы установки/получения: обычно используемый deserializeFromObject(JsonParser); p, DeserializationContext ctxt)методическийОсновная логика:
Вот краткое введение, для получения дополнительной информации вы можете обратиться к:
public class BeanPropertyMap implements Iterable<SettableBeanProperty>,java.io.Serializable
Учитывая тестовый класс в контроллере:
Укажите атрибуты в модели (методы установки/получания не перехватываются):
Используйте почтальона, чтобы проверить это, пример:
Приведенное выше изображение было кратко протестировано, но измерение не является исчерпывающим. Я не буду проверять его здесь со всеми, а приведу напрямую.
Вывод ①: @JsonAliasаннотация,Реализация: при преобразовании json в модель,Включите преобразование определенных ключей в json в определенные атрибуты модели, но только при преобразовании модели в json;, Соответствующий преобразованный ключ по-прежнему соответствует имени атрибута, см. запрос и ответ поля имени в приведенном выше примере. Следующий рисунок поясняет:
в это время,При преобразовании строки JSON в модель,jsonсерединаkeyдляName或дляname123或дляnameВсе можно узнать。
Вывод ②: @JsonPropertyаннотация,Реализация: при преобразовании json в модель,Включите преобразование определенных ключей в формате JSON в указанные атрибуты модели;,форма При преобразовании в json соответствующим преобразованным ключом является указанный ключ. См.: запрос и ответ поля девиза в примере. Следующий рисунок поясняет:
В настоящее время, когда строка json преобразуется в модель, ключ MOTTO можно распознать, но ключ MOTTO распознать невозможно.
Вывод ③:@JsonAlias аннотация需要依赖于setter、getter,Аннотация @JsonProperty не требуется.
Вывод ④:在不考虑上述两个аннотацияиз一般情况下,Когда ключ соответствует атрибуту, По умолчанию учитывается регистр.
Вывод ⑤:Есть несколько одинаковыхkeyизjson字符串середина,При конвертации в модель,будет в тех же ключах,排在最后из那个keyиз值给форма Введите копию атрибута, поскольку установщик перезапишет исходное значение. См. атрибут пола в примере.
Вывод ⑥:задняя часть@RequestBodyаннотация对应из类在将HTTPиз输入流(Содержит тело запроса)Собрать целевой класс(Прямо сейчас:@RequestBody后面 class), атрибуты соответствующего класса сущности будут сопоставляться в соответствии с ключом в строке json, если совпадение согласовано и значение соответствует ключу в json. Когда требования к типу соответствующего атрибута класса сущности удовлетворены (или могут быть преобразованы в него), будет вызван метод установки класса сущности для присвоения значения атрибуту.
Издатель: Лидер стека программистов полного стека, укажите источник для перепечатки: https://javaforall.cn/130013.html Исходная ссылка: https://javaforall.cn