1.前言
在对接三方平台时,其推送的数据中包含一个名为 cUserGuid
的字段。在项目联调过程中发现,虽然接收到的请求中该字段包含有效数值,但在服务端进行 JSON 反序列化(使用 Jackson 库)时,对应的 Java 对象字段值始终为空 (null
)。
经排查,确定此问题源于 Jackson 库默认的属性命名推导策略 与 JavaBean 规范 对于特定格式字段名的 getter/setter 方法命名规则存在冲突。
2. JavaBean命名处理
按照JavaBean的规范要求,getter 和 setter 方法的命名必须遵循以下模式:
Getter:
get
+<CapitalizedFieldName>
Setter:
set
+<CapitalizedFieldName>
关键点:首字母小写且次字母大写的字段名处理
当字段名的首字母小写且第二个字母大写时,规范要求生成 getter/setter 方法时,字段名的首字母在方法名中不应被大写。
以字段 cUserGuid
为例:
首字母 c小写。
第二个字母 U大写。
因此,其 getter 和 setter 方法应命名为 getcUserGuid()
和 setcUserGuid()
,而非 getCUserGuid()
和 setCUserGuid()
。
public String getcUserGuid() {
return cUserGuid;
}
public void setcUserGuid(String cUserGuid) {
this.cUserGuid = cUserGuid;
}
3.Jackson处理流程
Jackson 在反序列化 JSON 数据到 Java 对象时,需要将 JSON 属性名映射到 Java 对象的字段或方法上。其默认的推导过程(基于 getter/setter 方法名)如下:
移除方法前缀: 对于 getter (get) 或 setter (set),移除前缀。例如,getcUserGuid()移除 get后得到 cUserGuid。
处理首字母小写+次字母大写: Jackson 内置规则专门处理这种模式。它会将方法名移除前缀后得到的字符串(cUserGuid)中,从第二个字符开始连续的大写字母转换为小写,直到遇到第一个小写字母。
在 cUserGuid中,识别到 cU(首字母小写 c,次字母大写 U);
将 U及其后续连续的大写字母(此处 U后是 s,小写,故仅处理 U)转换为小写 u;
结果得到 cuserGuid。
匹配字段: Jackson 使用推导出的名称 cuserGuid去寻找 Java 对象中对应的字段(cuserGuid)或通过 setter 方法设置值。
4.解决方案
有多种解决方案,其中最简单的方式就是在字段上使用@JsonProperty,明确指定 JSON 属性名与 Java 字段/方法之间的映射关系,具体如下:
@JsonProperty("cUserGuid")
@NotBlank(message = "C端用户唯一标志不能为空")
private String cUserGuid;