背景
本项目组与其他项目组通过restful接口进行集成,后台返回的数据中有个字段叫rList.
使用spring的resttemplate集成时,该字段的值始终无法设置进去。
定位过程及思路
确认返回结果是否与本项目组定义的类型匹配
经排查,项目组定义的数据类型对比后端返回的结果,我们这边有部分字段缺失, --我们并不需要后端所有的字段
- 猜测,因为后端有些字段没在vo中定义,导致反序列化调用失败
进一步排查
- 经检查,部分字段有成功设值,所以应该没有序列化失败,肯定有某种原因导致rList这个字段反序列化失败
- 使用GSON,ObjectMapper等业界标准工具进行尝试,因为resttemplate默认的序列化工具比较小众,可能有bug。
– 发现:使用ObjectMapper提示
Unrecognized field “rList” (class xxx.type.xxxResponse), not marked as ignorable (7 known properties: “pageSize”, “totalPage”, “returnMessage”, “totalCount”, “returnCode”, “curPage”, “rlist”])
猜测
工具将rList字段的名字解析成rlist,导致和后端回传的字段名不一致,该字段的值没有被设置上
阅读工具源码,确定工具解析字段名称的规则
protected static String legacyManglePropertyName(String basename, int offset) {
int end = basename.length();
if (end == offset) {
return null;
} else {
char c = basename.charAt(offset);
char d = Character.toLowerCase(c);
if (c == d) {
return basename.substring(offset);
} else {
StringBuilder sb = new StringBuilder(end - offset);
sb.append(d);
for(int i = offset + 1; i < end; ++i) {
c = basename.charAt(i);
d = Character.toLowerCase(c);
if (c == d) {
sb.append(basename, i, end);
break;
}
sb.append(d);
}
return sb.toString();
}
}
}
序列化工具会通过set函数来确定字段在json中的名称。通过该端代码发现rList的set函数名称为setRList,工具解析后字段名为rlist。
解决方案
在字段或者其set函数上面加@JsonProperty注解
经验
序列化工具一般都是通过set函数对对象进行设置,set函数的命名规则为set+字段名(第一个字符大写)。
但是有些字段名第一个单词可能为缩写,这样工具为兼容这种情况,会导致rList这种命名的字段无法正确解析。
不同的工具解析字段名称的策略不一样,所以当反序列化的过程中没有抛出异常,但字段值却没有得到正确的设置,可以使用@JsonProperty等注解(不同的工具注解不一样),去明确告诉序列化工具该字段在json中的名字。