Java Bean 的命名规范 和 JSON 序列化库如何处理名称之间的不匹配问题
·
最近遇到一个很新奇的问题,之前从来没遇到过,用apifox测试的时候,传参但是在打断点的时候发现没有赋值成功。

[{
"cityCode": "xxx",
"cityName": "xx市",
"deptCode": "xxx",
"deptName": "xx部",
"cAdminName": "刘xx",
"cAdminAccount": "xxx",
"sAdminName": "xxx",
"sAdminAccount": "xxx"
}]
// 上面是我postman请求参数
// 这是我实体表的一部分代码(ps:实体类加的是@Data 注解)
private String cAdminName;
private String cAdminAccount;
private String sAdminName;
private String sAdminAccount;
private String cityCode;
private String cityName;
private String deptCode;
private String deptName;
但是打断点测试的时候,只有cityCode,cityName,deptCode,deptName这几个属性成功赋值了,剩下的都是空的!
经过一顿排查发现,这是由于 Java Bean 的命名规范 和JSON序列化库(如 Jackson)如何处理这些名称之间的不匹配所导致的。
简单来说,问题出在属性命名上。
问题的原因
JSON 库(例如 Spring Boot 默认的 Jackson)在将 JSON 字符串转换为 Java 对象时,需要依赖标准的 getter/setter 方法。
- 对于正常工作的字段:
- 一个名为 cityCode 的属性,按照 Java Bean 规范,它的 setter 方法是 setCityCode()。
- Jackson 看到 JSON 中的 "cityCode" 键,会正确地寻找并调用 setCityCode() 方法,因此赋值成功。deptName、cityName 等都是同理。
- 对于不工作的字段:
- 一个名为 cAdminName 的属性,按照 Java Bean 规范,它的 setter 方法应该是 setcAdminName() (请注意,c 是小写的)。
- 这是一个非常容易混淆的规范点。当属性名的第二个字母是大写时(如 cAdminName),第一个字母在 setter 方法名中保持小写。
- 然而,很多工具或开发者可能会误解这个规范,或者 Jackson 的某些版本/配置可能对此有不同的处理方式,它可能会错误地去寻找一个名为 setCAdminName()(大写 C)的方法。
- 当 Jackson 看到 JSON 中的 "cAdminName" 时,它试图找到一个合适的 setter 方法来给 cAdminName 属性赋值。因为它找不到一个完全匹配的、符合其内部规则的 setter(无论是 setcAdminName还是 setCAdminName 可能都不符合它此刻的查找逻辑),所以它只能静默地跳过这个字段的赋值。
- cAdminAccount、sAdminName 和 sAdminAccount 这几个字段都存在同样的问题,因为它们都遵循 xAbc... 这种命名模式。
核心结论: 失败的根本原因在于,对于 cAdminName 这类名称,序列化框架无法找到它期望的 setter 方法,因此放弃了对这些字段的赋值。
如何解决
有几种方法可以解决这个问题:
- 重命名属性:这是最清晰、最一劳永逸的办法。将 Java 实体类中的属性名改得不那么模棱两可。
- cAdminName -> cityAdminName
- sAdminName -> provinceAdminName
- 这样,setter 方法就会变成无歧义的 setCityAdminName(),JSON 键也相应地变成 "cityAdminName"。这完全消除了命名规范带来的困惑。
- 使用 @JsonProperty 注解(推荐的“修复”方案):如果您不想或不能修改属性名,可以使用此注解来明确地告诉 Jackson JSON 键和 Java 属性之间的映射关系。
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonProperty("cAdminName")
private String cAdminName;
这个注解会强制 Jackson 将 JSON 中的 cAdminName 键映射到这个字段,无论 setter 方法的命名是什么,通常能直接解决问题。
2. 手动编写 Setter:如果类没有使用 Lombok,可以为这几个有问题的字段手动编写标准的 setter 方法,确保命名正确(例如 public void setcAdminName(...))。如果正在使用 Lombok,这个方法就不太合适了。
综上所述,这个遇到的情况是一个很常见的 Java/JSON 映射问题,根源在于 cAdminName 这种命名方式的模糊性。
更多推荐
所有评论(0)