@RequestBody的使用

提示:建议一定要看后面的@RequestBody的核心逻辑源码以及六个重要结论本文前半部分的内容都是一些基
本知识常识,可选择性跳过。

声明:本文是基于SpringBoot,进行的演示说明。


基础知识介绍:

​ @RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);而最常用的使用请求体传参的无疑是POST请求了,所以使用@RequestBody接收数据时,一般都用POST方式进行提交。在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。

注:一个请求,只有一个RequestBody;一个请求,可以有多个RequestParam。

注:当同时使用@RequestParam()和@RequestBody时,@RequestParam()指定的参数可以是普通元素、
数组、集合、对象等等(即:当,@RequestBody 与@RequestParam()可以同时使用时,原SpringMVC接收
参数的机制不变,只不过RequestBody 接收的是请求体里面的数据;而RequestParam接收的是key-value
里面的参数,所以它会被切面进行处理从而可以用普通元素、数组、集合、对象等接收)。
即:如果参数时放在请求体中,application/json传入后台的话,那么后台要用@RequestBody才能接收到;
如果不是放在请求体中的话,那么后台接收前台传过来的参数时,要用@RequestParam来接收,或
则形参前 什么也不写也能接收。

注:如果参数前写了@RequestParam(xxx),那么前端必须有对应的xxx名字才行(不管其是否有值,当然可以通
过设置该注解的required属性来调节是否必须传),如果没有xxx名的话,那么请求会出错,报400。

注:如果参数前不写@RequestParam(xxx)的话,那么就前端可以有可以没有对应的xxx名字才行,如果有xxx名
的话,那么就会自动匹配;没有的话,请求也能正确发送。
追注:这里与feign消费服务时不同;feign消费服务时,如果参数前什么也不写,那么会被默认是
@RequestBody的。

如果后端参数是一个对象,且该参数前是以@RequestBody修饰的,那么前端传递json参数时,必须满足以下要求:

  • 后端@RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即:@RequestBody后面的类)时,会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值符合(或可转换为),这一条我会在下面详细分析,其他的都可简单略过,但是*****本文末的核心逻辑代码以及几个结论一定要看!***** 实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该属性。
  • json字符串中,如果value为"“的话,后端对应属性如果是String类型的,那么接受到的就是”",如果是后端属性的类型是Integer、Double等类型,那么接收到的就是null。
  • json字符串中,如果value为null的话,后端对应收到的就是null。
  • 如果某个参数没有value的话,在传json字符串给后端时,要么干脆就不把该字段写到json字符串中;要么写value时, 必须有值,null 或"“都行。千万不能有类似"stature”:,这样的写法,如:

img

注:关于@RequestParam()的用法,这里就不再一一说明了,可详见 《程序员成长笔记(一)》中的相关章节。


示例详细说明:

先给出两个等下要用到的实体类

User实体类:

img

Team实体类:

img

@RequestBody直接以String接收前端传过来的json数据:

后端对应的Controller:

img

使用PostMan测试:

img

***@RequestBody以简单对象接收*前端传过来的json数据:

后端对应的Controller:

img

使用PostMan测试:

img

@RequestBody以复杂对象接收前端传过来的json数据:

后端对应的Controller:

img

使用PostMan测试:

img

@RequestBody与简单的@RequestParam()同时使用:

后端对应的Controller:

img

使用PostMan测试:

img

@RequestBody与复杂的@RequestParam()同时使用:

后端对应的Controller:

img

使用PostMan测试:

img

@RequestBody接收请求体中的json数据;不加注解接收URL中的数据并组装为对象:

后端对应的Controller:

img

使用PostMan测试:

img

注:如果在后端方法参数前,指定了@RequestParam()的话,那么前端必须要有对应字段才行(当然可以通过设置
该注解的required属性来调节是否必须传),否者会报错;如果参数前没有任何该注解,那么前端可以传,也可
以不传,如:

img

上图中,如果我们传参中没有指定token,那么请求能正常进去,但是token为null;如果在String token前指定了@RequestParam(“token”),那么前端必须要有token这个键时,请求才能正常进去,否者报400错误。


@RequestBody与前端传过来的json数据的匹配规则

声明:根据不同的Content-Type等情况,Spring-MVC会采取不同的HttpMessageConverter实现来进行信息转换解析。
下面介绍的是最常用的:前端以Content-Type 为application/json,传递json字符串数据;后端以@RequestBody
模型接收数据的情况。

解析json数据大体流程概述:
Http传递请求体信息,最终会被封装进com.fasterxml.jackson.core.json.UTF8StreamJsonParser中(提示:Spring采用CharacterEncodingFilter设置了默认编码为UTF-8),然后在public class BeanDeserializer extends BeanDeserializerBase implements java.io.Serializable中,通过public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt)\throws IOException方法进行解析。

核心逻辑分析示例:

​ 假设前端传的json串是这样的: {“name1”:“邓沙利文”,“age”:123,“mot”:“我是一只小小小小鸟~”} 后端的模型只有name和age属性,以及对应的setter/getter方法;给出一般用到的deserializeFromObject(JsonParser p, DeserializationContext ctxt)方法的核心逻辑:

img


小技巧之指定模型中的属性对应什么key

这里简单介绍,更多的可参考:

public class BeanPropertyMap implements Iterable,java.io.Serializable

给出Controller中的测试类:

img

给出模型中的属性(setter/getter方法没截出来):

img

使用postman测试一下,示例:

img

上图简单测试了一下,但是测得并不全面,这里就不带大家一起测试了,直接给出。


全面的结论

结论 ①@JsonAlias注解,实现:json转模型时,使json中的特定key能转化为特定的模型属性;但是模型转json时,
对应的转换后的key仍然与属性名一致,见:上图示例中的name字段的请求与响应。
以下图进一步说明:

img

​ 此时,json字符串转换为模型时,json中key为Name或为name123或为name的都能识别。

结论②@JsonProperty注解,实现:json转模型时,使json中的特定key能转化为指定的模型属性;同样的,模
型转json时,对应的转换后的key为指定的key,见:示例中的motto字段的请求与响应。
以下图进一步说明:

img

​ 此时,json字符串转换为模型时,key为MOTTO的能识别,但key为motto的不能识别。

结论③@JsonAlias注解需要依赖于setter、getter,而@JsonProperty注解不需要。

结论④在不考虑上述两个注解的一般情况下,key与属性匹配时,默认大小写敏感。

结论⑤有多个相同的key的json字符串中,转换为模型时,会以相同的几个key中,排在最后的那个key的值给模
型属性复制,因为setter会覆盖原来的值。见示例中的gender属性。

结论⑥后端@RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即:@RequestBody后面
的类)时,会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值
符合(或可转换为)实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该属性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/556890.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql 字段值为 a b c_数据的虚拟列-让数据库中的C字段等于a+b

直接用update aaaaa aa set aa.f (aa.aaa.b)就行了引出来的新知识--虚拟列虚拟列的好处是:如果cab那插入数据时;值只插入a1,b2;那么c会自动是3oracle temporary table and virtual column(2013-07-31 15:06:55)表是数据库中保存用户数据最基本的结构。下面我简要的…

@RequestBody 和 @RequestParam可以同时使用

RequestParam和RequestBody这两个注解是可以同时使用的。 网上有很多博客说RequestParam 和RequestBody不能同时使用,这是错误的。根据HTTP协议,并没有说post请求不能带URL参数,经验证往一个带有参数的URL发送post请求也是可以成功的。只不过…

mysql索引使增删变慢_mysql优化之索引篇

mysql,对it打工人,这个几乎是必备的技能之一。mysql可以解决我们平时工作中的大量的、有关增删查改的问题。所以想深入了解mysql,我觉得关键在于他的增删查改背后的算法,开搞。面对增删查改等问题,直接通过场景来看吧场…

POST、GET、@RequestBody和@RequestParam区别

RequestParam 注解RequestParam接收的参数是来自HTTP请求体或请求url的QueryString中。 RequestParam可以接受简单类型的属性,也可以接受对象类型。 RequestParam有三个配置参数: required 表示是否必须,默认为 true,必须。de…

python与linux关系_如何处理Linux / Python依赖关系?

由于缺乏对我想使用的一些库的支持,我将一些Python开发从Windows转移到Linux开发.我已经花了大部分时间搞乱了依赖关系.问题每当我拿起Linux,我通常会遇到一些依赖问题,通常是开发库,无论是通过apt-get,easy_install或pip安装.我可以浪费时间,应该是简单的任务,花更长的时间让图…

Springmvc接收json数据的4种方式

1、以RequestParam接收 前端传来的是json数据不多时:[id:id],可以直接用RequestParam来获取值 Autowired private AccomodationService accomodationService;RequestMapping(value "/update") ResponseBody public String updateAttr(RequestParam (&q…

centos安装mysql卡住_CentOS 6.4安装MySQL的过程中出现的bug

在CentOS 6.4下安装MySQL,下载一个源码包,感觉很简单,tar,./configure,make,make install 经典四步,弄这个也不是第一次了,但今天就是老出错,首先是./configure中&#x…

SpringMVC接受List的几种方式

说到SpringMVC接受List参数,可能有人会说这个是个坑!下面我来跟大家说怎么补这个坑。下面我分几种情况来讲: 一、只接收一个List 1、form表单提交 controller代码: ResponseBody RequestMapping("test") public voi…

mysql怎么加固_mysql安装及加固

mysql安装查看是否安装mysql我们先看一下有没有安装mysqlyum list installed mysql | grep mysql本地只安装了php链接mysql的库,没有安装mysql如果有安装,可以使用安装的或者卸载了重新安装添加yum源去mysql官网查找下面我就来安装下yum源sudo rpm -ivh …

python标准库os的方法listdir_使用python标准库快速修改文件名字

大家在追剧的时候会一次性下载很多电影,但是很烦人的是前面会有很多电影网站的广告前缀。今天我将介绍一个简短的代码,快速修改这些文件的名字。工具:os首先在电影目录下新建一个py文件,并导入osimport osos,是python中…

RabbitMQ保姆级教程

文章目录 前言一、MQ是什么? 1.1 AMQP 二、在Linux安装RabbitMQ 2.1 安装2.2 RabbitMQ启动命令2.3 开启RabbitMQ 后台管理界面 2.3.1 登录rabbitMQ UI界面 2.3 Docker启动RabbitMQ2.4 常见消息模型2.5 生产者(Producer) / 消费者(Consumer)2.6 工作队列模式(Work Q…

spring mysql 连接池配置_SpringBoot数据库连接池常用配置

关注公众号:程序猿王国 持续更新,每日分享在配置文件中添加配置如下(我使用的是多数据源):spring.datasource.primary.urljdbc\:mysql\://localhost\:3306/test?useUnicode\true&characterEncoding\utf-8spring.datasource.prim…

交换机到底是啥?

1、交换机 交换机个人资料: 1.证件照 注:copy 百度百科 我的博客/交换机到底是啥? 这东西乍一看有点像月光宝盒,是不是。 2.个人简介 交换机(Switch)意为“开关”是一种用于电(光&#xff0…

unity3d 动态合批设置_Unity3D SkinnedMeshRenderer合批优化

最近做了性能优化相关的工作,其中一些是关于战斗模块的渲染的。主要是对场景中使用的基于SkinnedMeshRenderer的网格进行了一些合批优化(降DC),记录如下。项目使用的Unity版本为5.6.4p1。游戏中的战斗模块是这样的:战斗逻辑由服务器承担&…

java——Final修饰成员变量的注意事项

一.Final 修饰成员变量的注意事项 final修饰成员变量,该成员变量必须在创建对象之前进行赋值,否则编译失败final修饰成员变量,固定的不是成员变量拥有的默认值,如果固定的是默认值,那么将导致被final修饰的…

php 编写mysql_php编写数据写入mysql问题

我刚写好的:前台是htm界面填写数据留言板...我刚写好的:前台是 htm界面 填写数据留言板你的姓名:你的性别:男 女你的email:你的留言内容:后台是:if(isset($_POST)) // 只有 $_POST 变量存在&…

java 代码 点到线段的最短距离

// 点到直线的最短距离的判断 点(x0,y0) 到由两点组成的线段(x1,y1) ,( x2,y2 )private double pointToLine(int x1, int y1, int x2, int y2, int x0,int y0) {double space 0;double a, b, c;a lineSpace(x1, y1, x2, y2);// …

isNotBlank()和isNotEmpty()的区别——java中,StringUtils类中的一些常用方法

java中,StringUtils类中的一些常用方法 boolean isBlank(String str) //判断某字符串是否为空或长度为0或由空白符(whitespace)构成 StringUtils.isBlank(null) true StringUtils.isBlank("") true StringUtils.isBlank(" ") true StringUt…

java类的加载顺序_java类加载先后顺序

这里讲的不是类加载机制,是类的加载先后顺序。话不多说了,先设定以下场景:package com.jingdong;public class A {public static void main(String[] args){System.out.println(Ib.b);B bnew B();b.ibTest();}}public class B implements Ib{private D d;private C …

MyBatis:模糊查询的4种实现方式

1、根据姓名模糊查询员工信息 1.1、方式一 步骤一:编写配置文件 步骤二:测试 步骤三:分析 此种方式需要在调用处手动的去添加“%”通配符。 1.2、方式二 说明: 使用方式一可以实现模糊查询,但是有一点不方便的地…