@RequestBody 注解无法解析对象中首字母小写,第二个字母大写的属性(Jackson 的原因)
2024-4-16 22:00
例如属性为 eName
当 get/set 方法名称为 getEName/setEName 的时候,会因为 Jackson 在处理完 getEName/setEName 后无法找到对应的属性
Lombok 也是,由于 Lombok 生成的 get/set 方法的语义规范与 Jackson 处理 get/set 方法不一致,所以会导致的属性名无法匹配。
以下流程参考: https://zhuanlan.zhihu.com/p/628668559 (写得很详细)
Jackson 的处理流程:
- 首先会根据
offset
字段去除前面的三个字母,一般为 get 或 set - 去除前面三个字母
set
后,发现第一个字母E
是大写的,因此将第一个字母小写成e
,然后接着往后找,如果后面的还是大写,接着变小写…直到找到了一个本来就是小写的字母后,才将后面所有的字母一股脑添加进来。
由于 setEName
在去除前面的 set 后,前面两个字母都是大写,因此在这种处理逻辑下,最后得到的属性名为 ename
。
换句话说,如果 set 方法的名称是 seteName
,那么处理后得到的就是正确的 eName
。
所以解决方案:
- 使用 Lombok 的配置来解决。在项目根目录下创建
lombok.config
文件,并添加配置项lombok.accessors.capitalization = beanspec
即可 - 改 get/set 的方法名
- 利用 Jackson 的 JsonProperty 注解强行指定属性名(推荐在get方法上标注)
但由于 Lombok 和 ptg 插件都只能生成属性名首字母大写的 get/set 方法,如果实在懒得自己写,可以用 @JsonProperty
来标注该属性在 JSON 中的名称
但是:使用 @JsonProperty 注解标注属性,序列化时会多出一个字段(参考 ”使用 @JsonProperty 注解标注属性导致序列化时多出一个字段的原因“ 的内容)
先说结论,只需要满足以下两个条件之一即可解决序列化和反序列化的问题
- 在 get 方法上标注 @JsonGetter(“name”) 或者 @JsonProperty(“name”) ————推荐在 get 方法上标注 @JsonProperty
- 在 set 方法上标注 @JsonSetter(“name”) 或者 @JsonProperty(“name”)