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()方法无法识别参数。
不过我感觉这样子说的太笼统了,无法解答我的困惑。
后来我仔细研究了一下,简单说一下我的看法和理解吧。
首先我在实体类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反序列化给实体类的具体过程可以参考一下这篇:@RequestBody的使用_JustryDeng-CSDN博客_@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、参考资料
- Springboot | @RequestBody 接收到的参数对象属性为空 - 走看看
- 使用@RequestBody注解,接收不到参数,参数为NULL - 程序员大本营
- @RequestBody注解原理 - 简书
- @RequestBody的使用_JustryDeng-CSDN博客_@requestbody
- @RequestBody和@ResponseBody和消息转换器机制原理_Hedwig的博客-CSDN博客_requestbody 原理
- @JsonProperty使用详解_0bug0warning的博客-CSDN博客_@jsonproperty
- 序列化和反序列化的详解_tree_ifconfig的博客-CSDN博客_序列化和反序列化
- 什么是驼峰命名法_百度知道
Spring中使用@RequestBody注解接收的实体类中的某些参数为null的更多相关文章
- 使用Spring MVC的@RequestBody注解接收Json对象字符串
最近公司在开发移动APP,APP上通过jQuery提交表单的json字符串格式数据到Java后端,之前通过request手动接收,非常麻烦,其实Spring MVC已经为我们提供了一个注解@Reque ...
- resultMap自定义映射---8.3.1. 解决列名(表中的字段名称)和实体类中的属性名不一致
1.1.1.1. 步骤一:将驼峰匹配注释掉 --------------测试完成后仍然 回来开启 其他地方可能用到 一旦注释掉驼峰匹配,那么再通过queryUserById查询的结果中,用 ...
- spring中RequestBody注解接收参数时用JSONField转参数名无效问题
问题: 在springboot项目中使用@RequestBody注解接收post请求中body里的json参数的情况.即: @RequestMapping(value = "/get-use ...
- MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致
MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致 情景:当数据库中的列名与我们程序实体类中的字段名称不一致 使用ResultMap节点配置信息 在映射文件中 ...
- Hibernate jpa 在实体类中对于时间的注解
在时间类型DATE 属性上添加一个 @Temporal(TemporalType.DATE)(精确到年月日)@Temporal(TemporalType.TIME)(精确到时分秒)@Temporal( ...
- 【spring data jpa】repository中使用@Query注解使用hql查询,使用@Param引用参数,报错:For queries with named parameters you need to use provide names for method parameters. Use @Param for query method parameters, or when on
在spring boot中, repository中使用@Query注解使用hql查询,使用@Param引用参数 如题报错: For queries with named parameters you ...
- 解决Entity 实体类中加了@Id 注解后仍然出现org.hibernate.AnnotationException: No identifier specified for entity 错误
启动报错如下图所示: 解决方案: 查看网上的资料,大部分都说在实体类中没有添加加主键的注解@Id,这个是必须的.但是我的实体类中明明已经添加了@Id,为什么还会报这个错误呢? 后来检查了很久,发现是我 ...
- 读取Excel文件存储在实体类中
1.Maven文件 <!--读取Excel的架包--> <dependency> <groupId>org.apache.poi</groupId> & ...
- 当实体类中entity/DTO/VO等类中,有枚举值,应该怎么输出?
当实体类中entity/DTO/VO等类中,有枚举值,应该怎么输出? 问题: orderStatus 和 payStatus都是枚举类,并且枚举的个数达地10来个,我们不可能在模板页面(jsp/ftl ...
随机推荐
- RNN自学理解(一)
RNN对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,利用了RNN的这种能力,使深度学习模型在解决语音识别.语言模型.机器翻译以及时序分析等NLP领域的问题时有所突破. 参考文献1 ...
- 删除数组里含有a的元素,并且将null值放在后面
想去掉里面含有a的元素,并将null放在后面.放在后面就是往后移,其他值往左移 1 public static void main(String[] args) { 2 //自定义的一个数组 3 St ...
- 齐博x1直播要设置回调地址才能播放
因为通过扫码或推流网址给第三方用,也能让圈子实现直播,所以系统就改为必须要设置回调地址才能播放视频了.下面阿里与腾讯的都是大同小异的.腾迅的有多项,阿里的只有一项,不过阿里其实还有另一项,就是录制的时 ...
- Windows 环境搭建 PostgreSQL 逻辑复制高可用架构数据库服务
本文主要介绍 Windows 环境下搭建 PostgreSQL 的主从逻辑复制,关于 PostgreSQl 的相关运维文章,网络上大多都是 Linux 环境下的操作,鲜有在 Windows 环境下配置 ...
- android学习 基础知识
布局管理器 大小用dp; 字体用sp 线性布局 与 相对布局是可以嵌套使用的,根据实际需求,灵活使用. 1.通用属性 # 大小相关 layout_width="100dp":宽度 ...
- 【Zulip】邮件系统配置
通过docker-compose(docker-zulip)部署Zulip实例时需要配置邮件系统 SETTING_ZULIP_ADMINISTRATOR: '...@qq.com' SETTING_E ...
- 嵌入式-C语言:通过结构体指针操作结构体内容
#include<stdio.h> #include<string.h> struct Student { char name[32]; int age; int height ...
- 关于li标签的相关css属性
1.让li前面的序号变成空心圆 list-style-type: circle; 2.让li前面的序号在div里面 list-style-position: inside; 3.改变li前面的 ...
- 23、有一个字符串,包含n个字符,编写一函数,将此字符串中从第m个字符开始的全部字符串复制成另一个字符串
/* 有一个字符串,包含n个字符,编写一函数,将此字符串中从第m个字符开始的全部字符串复制成另一个字符串 */ #include <stdio.h> #include <stdlib ...
- Java-(array)数组的基本概念 及 Java内存划分
(array)数组的基本概念 数组的概念:是一种容器,可同时存放多个数据值 数组的特点: 1.数组是一种引用数据类型 2.数组当中的多个数据,类型必须统一 3.数组的长度在程序运行期间不可改变 数组的 ...