在开发中, 有的时候变量命名会影响到 jackson 的序列化 / 反序列化
问题: postman 中传输 json 参数, 后台始终接收为 null, 字段明明匹配 (复制粘贴的), 但是就是收不到传过来的参数. 后来发现是 jackson 对于单字母的驼峰命名会特殊处理为小写, 导致前端传了同名参数, 后端却收不到的情况, 很坑.
例如, 我们自定义对象中, 有个属性是 kIdTypeList (注意 字母 I 是大写的)
@Data
public class Person {
/**
*
*/
private List<String> kIdTypeList;
}
jackson 在序列化 / 反序列化时, 默认取值/生成的字段并不是 kIdTypeList
而不是 kIdTypeList
(注意 jackson 是按照字母 i 小写的形式取值和生成 json 的, 这不是我们期望的
/**
* jackson 单字母驼峰问题 前端传 kidTypeList, 后端使用 kIdTypeList 才能接收到
* 解决 @JsonProperty(value = "kIdTypeList") 显式声明
* 问题排查方式: 命名的问题, 改名解毒
*/
@Test
public void testField() {
Person person = new Person();
// 单字母的驼峰命名, kIdTypeList 会输出为 kidTypeList, 同样接收参数时也是取 kidTypeList
// 此时务必显式声明 @JsonProperty(value = "kIdTypeList") 才行
List<String> kIdTypeList = Lists.newArrayList();
kIdTypeList.add("123");
person.setKIdTypeList(kIdTypeList);
String text = JacksonUtils.toJSONString(person);
System.out.println(text);
// 由于字段声明为 kIdTypeList, jackson 会默认取 kidTypeList, 很坑
text = "{\"kIdTypeList\":[\"123\"]}";
Person p = JacksonUtils.parse(text, Person.class);
System.out.println(p);
}
总结:
jackson 解析的字段中有单个字母作为驼峰单词的, 单个字母后面的大写字母会默认取小写的, 而不是原样取值.
解决:
如果使用 jackson 作为 json 解析工具 (springboot 默认使用 jackson), 并且字段是单个字母作为驼峰单词的, 那么, 在该字段上显式声明 @JsonProperty(value = "kIdTypeList")
即可原样取值和输出 json
BTW: fastjson 没有此问题
stackoverflow 上有人也遇到了相同问题