@RequestBody 注解无法解析对象中首字母小写,第二个字母大写的属性(Jackson 的原因)

473 阅读2分钟

@RequestBody 注解无法解析对象中首字母小写,第二个字母大写的属性(Jackson 的原因)

2024-4-16 22:00

例如属性为 eName

当 get/set 方法名称为 getEName/setEName 的时候,会因为 Jackson 在处理完 getEName/setEName 后无法找到对应的属性

Lombok 也是,由于 Lombok 生成的 get/set 方法的语义规范与 Jackson 处理 get/set 方法不一致,所以会导致的属性名无法匹配。

以下流程参考: zhuanlan.zhihu.com/p/628668559 (写得很详细)

Jackson 的处理流程:

  • 首先会根据 offset字段去除前面的三个字母,一般为 get 或 set
  • 去除前面三个字母 set 后,发现第一个字母 E 是大写的,因此将第一个字母小写成 e,然后接着往后找,如果后面的还是大写,接着变小写...直到找到了一个本来就是小写的字母后,才将后面所有的字母一股脑添加进来。

由于 setEName 在去除前面的 set 后,前面两个字母都是大写,因此在这种处理逻辑下,最后得到的属性名为 ename

换句话说,如果 set 方法的名称是 seteName ,那么处理后得到的就是正确的 eName

所以解决方案:

  1. 使用 Lombok 的配置来解决。在项目根目录下创建 lombok.config文件,并添加配置项lombok.accessors.capitalization = beanspec即可
  2. 改 get/set 的方法名
  3. 利用 Jackson 的 JsonProperty 注解强行指定属性名(推荐在get方法上标注)

但由于 Lombok 和 ptg 插件都只能生成属性名首字母大写的 get/set 方法,如果实在懒得自己写,可以用 @JsonProperty 来标注该属性在 JSON 中的名称

但是:使用 @JsonProperty 注解标注属性,序列化时会多出一个字段(参考 ”使用 @JsonProperty 注解标注属性导致序列化时多出一个字段的原因“ 的内容)

先说结论,只需要满足以下两个条件之一即可解决序列化和反序列化的问题

  • 在 get 方法上标注 @JsonGetter("name") 或者 @JsonProperty("name") ————推荐在 get 方法上标注 @JsonProperty
  • 在 set 方法上标注 @JsonSetter("name") 或者 @JsonProperty("name")