记一次json序列化采坑

背景

本项目组与其他项目组通过restful接口进行集成,后台返回的数据中有个字段叫rList.
使用spring的resttemplate集成时,该字段的值始终无法设置进去。

定位过程及思路

确认返回结果是否与本项目组定义的类型匹配

经排查,项目组定义的数据类型对比后端返回的结果,我们这边有部分字段缺失, --我们并不需要后端所有的字段

  • 猜测,因为后端有些字段没在vo中定义,导致反序列化调用失败

进一步排查

  1. 经检查,部分字段有成功设值,所以应该没有序列化失败,肯定有某种原因导致rList这个字段反序列化失败
  2. 使用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中的名字。

你可能感兴趣的:(java,json,java,spring)