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 ...
随机推荐
- Linux安装中文字体(已验证)
1.安装字体命令 sudo apt install -y fontconfig 2.查看已安装的字体 (1)查看linux已安装字体 fc-list (2)查看linux已安装中文字体 fc-list ...
- RAID5 IO处理之replace代码详解
1 作用 从字面意思理解,replacement即是替换.我们知道硬盘都有一定的使用寿命,可以在硬盘失效之前通过该功能将就盘的数据迁移至新盘.因为replacement的流程是从旧盘中读出数据直接写入 ...
- 检测 MySQL 服务是否存活 shell脚本
#!/bin/bash # 检测 MySQL 服务是否存活 # host 为你需要检测的 MySQL 主机的 IP 地址,user 为 MySQL 账户名,passwd 为密码 # 这些信息需要根据实 ...
- echarts的使用 超好用的报表制作、数据的图形化展示
地址链接:https://echarts.apache.org/zh/index.html 1.图形选择 2.对应的js代码
- 给 hugo 博客添加搜索功能
起因 我的博客使用了 hugo 作为静态生成工具,自带的主题里也没有附带搜索功能.看来,还是得自己给博客添加一个搜索功能. 经过多方查找,从 Hugo Fast Search · GitHub 找到一 ...
- 【一】ERNIE:飞桨开源开发套件,入门学习,看看行业顶尖持续学习语义理解框架,如何取得世界多个实战的SOTA效果?
参考文章: 深度剖析知识增强语义表示模型--ERNIE_财神Childe的博客-CSDN博客_ernie模型 ERNIE_ERNIE开源开发套件_飞桨 https://github.com/Pad ...
- 一、Vue.js介绍
一.介绍 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅易于上手 ...
- 支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇是<支持JDK19虚拟线程的web ...
- node 学习笔记 模块和包的管理与使用
1.前言 对于各种编程语言,代码组织是很重要的.而模块是node中的代码组织机制,node中的很多功能都以模块划分,而模块中又封装了许多方法,而且不会改变全局作用域,极大的方便了各开发者的需求. 2. ...
- 论文笔记 - An Explanation of In-context Learning as Implicit Bayesian Inference
这位更是重量级.这篇论文对于概率论学的一塌糊涂的我简直是灾难. 由于 prompt 的分布与预训练的分布不匹配(预训练的语料是自然语言,而 prompt 是由人为挑选的几个样本拼接而成,是不自然的自然 ...