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、参考资料

Spring中使用@RequestBody注解接收的实体类中的某些参数为null的更多相关文章

  1. 使用Spring MVC的@RequestBody注解接收Json对象字符串

    最近公司在开发移动APP,APP上通过jQuery提交表单的json字符串格式数据到Java后端,之前通过request手动接收,非常麻烦,其实Spring MVC已经为我们提供了一个注解@Reque ...

  2. resultMap自定义映射---8.3.1. 解决列名(表中的字段名称)和实体类中的属性名不一致

    1.1.1.1.      步骤一:将驼峰匹配注释掉 --------------测试完成后仍然 回来开启  其他地方可能用到 一旦注释掉驼峰匹配,那么再通过queryUserById查询的结果中,用 ...

  3. spring中RequestBody注解接收参数时用JSONField转参数名无效问题

    问题: 在springboot项目中使用@RequestBody注解接收post请求中body里的json参数的情况.即: @RequestMapping(value = "/get-use ...

  4. MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致

    MyBatis系列二  之   数据库列名于程序实体类中字段名称不一致 情景:当数据库中的列名与我们程序实体类中的字段名称不一致         使用ResultMap节点配置信息  在映射文件中  ...

  5. Hibernate jpa 在实体类中对于时间的注解

    在时间类型DATE 属性上添加一个 @Temporal(TemporalType.DATE)(精确到年月日)@Temporal(TemporalType.TIME)(精确到时分秒)@Temporal( ...

  6. 【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 ...

  7. 解决Entity 实体类中加了@Id 注解后仍然出现org.hibernate.AnnotationException: No identifier specified for entity 错误

    启动报错如下图所示: 解决方案: 查看网上的资料,大部分都说在实体类中没有添加加主键的注解@Id,这个是必须的.但是我的实体类中明明已经添加了@Id,为什么还会报这个错误呢? 后来检查了很久,发现是我 ...

  8. 读取Excel文件存储在实体类中

    1.Maven文件 <!--读取Excel的架包--> <dependency> <groupId>org.apache.poi</groupId> & ...

  9. 当实体类中entity/DTO/VO等类中,有枚举值,应该怎么输出?

    当实体类中entity/DTO/VO等类中,有枚举值,应该怎么输出? 问题: orderStatus 和 payStatus都是枚举类,并且枚举的个数达地10来个,我们不可能在模板页面(jsp/ftl ...

随机推荐

  1. C++面向对象编程之类的写法

    1.头文件中的防卫式声明 例如自己要建复数complex类,可以建立一个complex.h的头文件. 头文件中必须先写防卫式声明: #ifndef __COMPLEX__ #define __COMP ...

  2. POJ1734 Sightseeing trip (Floyd求最小环)

    学习了一下用Floyd求最小环,思路还是比较清晰的. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring ...

  3. POJ2955 Brackets (区间DP)

    很好的区间DP题. 需要注意第一种情况不管是否匹配,都要枚举k来更新答案,比如: "()()()":dp[0][5]=dp[1][4]+2=4,枚举k,k=1时,dp[0][1]+ ...

  4. MySQL基础、MySQL安装和MariaDB安装

    MySQL基础 目录 MySQL基础 关系型数据库介绍 数据结构模型 RDBMS专业名词 关系型数据库的常见组件 SQL语句 MySQL安装与配置 MySQL安装 MariaDB安装 关系型数据库介绍 ...

  5. Goland Socket 服务

    客户端发送消息 并接收服务端消息 package main import ( "fmt" "net" ) func main() { // conn, err ...

  6. python 运行错误收集

    目录 global全局声明错误 global全局声明错误 SyntaxError: name 'is_login' is used prior to global declaration 解决办法:g ...

  7. vulnhub靶场之EMPIRE

    准备: 攻击机:虚拟机kali.本机win10. 靶机:EMPIRE: BREAKOUT,地址我这里设置的桥接,下载地址:https://download.vulnhub.com/empire/02- ...

  8. 实验6:开源控制器实———RYU

    一.实验目的 1.能够独立部署RYU控制器: 2.能够理解RYU控制器实现软件定义的集线器原理: 3.能够理解RYU控制器实现软件定义的交换机原理. 二.实验环境 Ubuntu 20.04 Deskt ...

  9. 图文详解丨iOS App上架全流程及审核避坑指南

    App Store作为苹果官方的应用商店,审核严格周期长一直让用户头疼不已,很多app都"死"在了审核这一关,那我们就要放弃iOS用户了吗?当然不是!本期我们从iOS app上架流 ...

  10. 廖---list tuple dic set

    list 有序集合,可随时添加和删除其中的数据. 在 Python 列表中删除元素主要分为以下 3 种场景: 根据目标元素所在位置的索引进行删除,可以使用 del 关键字或者 pop() 方法: 根据 ...