Spring中使⽤@RequestBody注解接收的实体类中的某些参数为null
1、问题描述
我写完⼀个接⼝,在⽤postman测试的时候,发现其中有⼀个参数cEnterpriseId明明是有值的,但接⼝controller接收到的该参数为null,但其他参数都不为null的。
2、解决⽅法
我⾸先去百度了⼀下,说是由于实体类的参数命名不规范导致的,没有按照标准“驼峰法”进⾏参数命名。也可以在实体类相应的参数上加上@JsonProperty(value="xxx")来解决。
解决⽅法⼀、
加@JsonProperty注解
在实体类的cEnterpriseId参数上加上@JsonProperty(value = "cEnterpriseId")就解决了。
解决⽅法⼆、
⼿动在实体类添加get / set⽅法
解决⽅法三、
把postman传参的cEnterpriseId改成⼩写centerpriseId
3、产⽣原因
我看⽹上不少说产⽣类似的问题@RequestBody获取的参数为null是由于springboot解析器在解析json过程中出现问题,因字段名驼峰命名⽆法匹配字段名导致。spring框架在接收参数的时候的get()⽅法⽆法识别参数。
springboot其实就是spring不过我感觉这样⼦说的太笼统了,⽆法解答我的困惑。
后来我仔细研究了⼀下,简单说⼀下我的看法和理解吧。
⾸先我在实体类CustomerUsecaseJourneyBO上加了@Data注解,@Data注解⼤家应该都熟悉,就是⽤来⽣成实体类的get和set⽅法并隐藏get/set⽅法的。
那么对于cEnterpriseId这个参数,@Data注解⾃动为它⽣成的get/set⽅法是这样⼦的:
然后我⽤idea⼯具,⾃动在实体类中⽣成了⼀下cEnterpriseId的get/set⽅法。
@Data⽣成的是getCEnterpriseId()/setCEnterpriseId(),⽽idea⾃动⽣成的是getcEnterpriseId()/setcEnterpriseId()。
我⽤postman传⼀个json到接⼝,json在传输过程中会被转为“字节流”。接⼝controller层的@RequestBody加在实体类参数前⾯,会把接收到的字节流反序列成为⼀个java 实体类。@RequestBody在反序列化的时候给实体类赋值使⽤的get/set⽅法是同idea⾃动⽣成的get/set⽅法,即:getcEnterpriseId()/setcEnterpriseId()。所以
@RequestBody是⽤setcEnterpriseId()给是实体类CustomerUsecaseJourneyBO赋值,但在CustomerUsecaseJourneyBO类中setcEnterpriseId()是不存在
的,CustomerUsecaseJourneyBO类中只有setCEnterpriseId()。
setcEnterpriseId() 不等于 setCEnterpriseId()。
当然其实也可以不加@JsonProperty注解,只需修改⼀下postman传参的⼤⼩写就⾏了。
把cEnterpriseId改成centerpriseId,因为centerpriseId对应的get/set⽅法是getcEnterpriseId()/setcEnterpriseId()。
梳理了⼀下,⼤致的流程是这样的
关于json被@RequestBody反序列化给实体类的具体过程可以参考⼀下这篇:
4、总结
@RequestBody反序列化实体类部分值为null,这个问题以前没有碰到过,后来经研究发现竟然是参数命名不符合“驼峰法”,cEnterpriseId对应的数据库表字段是
c_enterpriseId,我的idea⼯具装了阿⾥巴巴代码规范检测插件明明检查结果是“cEnterpriseId”是⼀个合法的参数命名,因此是因为cEnterpriseId命名不规范导致
@RequestBody反序列化set不了实体类的参数,显然也是解释不通的。
不过我也是第⼀次发现注解@Data⽣成的get/set⽅法和idea⼯具⾃动⽣成的get/set在命名上竟然会不⼀致。
不过@Data⽣成的get/set⽅法是会被覆盖的。因此看来以后写实体类在加@Data注解时要多留个⼼眼,最好在实体类中写get/set⽅法,⽽不是通过@Data隐藏封装get/set ⽅法。另外如果涉及前端的json的化,最好⼀定要加@JsonProperty。来保证实体类中的字段与json⼀⼀对应上。
5、参考资料

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。