Jackson ObjectMapper序列化is_开头字段命名异常的原因是什么
现象产生原因
这个问题是Kotlin字节码生成规则和未配置Kotlin模块的Jackson默认Java Bean属性解析逻辑共同作用的结果,不存在专门过滤is_开头字段的逻辑,具体拆解如下:
- 未注册
KotlinModule的Jackson默认按照Java Bean规范序列化对象:不会直接读取类的字段,而是扫描类中所有public的getter方法,通过方法名反推序列化用的属性名:- 方法名以
get开头的,去掉前3个字符,将剩余字符串首字母小写作为属性名 - 方法名以
is开头的(Java Bean规范中这类getter本应只对应布尔类型属性),去掉前2个字符,将剩余字符串首字母小写作为属性名 - 扫描得到的getter方法默认按方法名字典序排列,直接决定序列化字段的输出顺序
- 方法名以
- Kotlin为类属性生成字节码时,对
is前缀的属性有特殊的getter生成规则:只要属性名以小写is开头,不管属性实际是什么类型,都不会生成getXxx格式的getter,而是直接生成和属性同名的getter方法。对应到示例代码:- 属性
something生成的getter是getSomething(),Jackson按规则解析出属性名something,方法名首字母g排序靠前,因此出现在序列化结果的靠前位置 - 属性
is_something生成的getter是is_something(),Jackson识别到方法以is开头,直接去掉前2个字符,得到属性名_something;同时该方法名首字母i排序在g之后,因此被调整到序列化结果的末尾
- 属性
- 最初误以为字段被忽略,是因为改名后的
_something和原字段名差异较大,第一眼容易漏看。
如果要避免这个问题,只需要给ObjectMapper注册
KotlinModule即可,此时Jackson会直接读取Kotlin类的原生属性元数据完成序列化,不再通过getter方法名反推属性名,is_something字段就会以原名正常输出。
内容的提问来源于stack exchange,提问作者user15941734
相关产品推荐
相关产品推荐

