Java 引用对象导致 jackson 反序列化结果不正确

2022-11-21 14:45:40 +08:00
 weofuh

为什么会使 map value 的 list 元素重复?

import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {

    public static void main(String[] args) throws Exception {
        ObjectMapper jackson = new ObjectMapper();

        Map<String, List<String>> map = new HashMap<>();
        map.put("key", Arrays.asList("a", "b", "c"));

        DataInfo dataInfo = new DataInfo(map);

        // {"map":{"key":["a","b","c"]},"copyList":["a","b","c"]}
        String json = jackson.writeValueAsString(dataInfo); 

        System.out.println(dataInfo.getMap().get("key").size()); // 3

        DataInfo di = jackson.readValue(json, DataInfo.class);
        System.out.println(di.getMap().get("key").size()); // 6
    }

    static class DataInfo {
        private Map<String, List<String>> map;

        public DataInfo() {
        }

        public DataInfo(Map<String, List<String>> map) {
            this.map = map;
        }

        //@Transient
        public List<String> getCopyList() {
            return map.get("key");
            //return new ArrayList<>(map.get("key"));
        }

        public Map<String, List<String>> getMap() {
            return map;
        }

        public void setMap(Map<String, List<String>> map) {
            this.map = map;
        }
    }
}

1051 次点击
所在节点    问与答
3 条回复
urnoob
2022-11-21 15:04:59 +08:00
```
Object toModify;
try {
toModify = this._getter.invoke(instance, (Object[])null);
} catch (Exception var6) {
this._throwAsIOE(p, var6);
return;
}

if (toModify == null) {
ctxt.reportBadDefinition(this.getType(), String.format("Problem deserializing 'setterless' property '%s': get method returned null", this.getName()));
}
this._valueDeserializer.deserialize(p, ctxt, toModify);
```
copyList 解析时 _getter 是 getCopyList , toModify 就是 map.get("key") 的结果 ,两者一 merge 不就是 6 了么。

感觉 DataInfo 的写法也很奇葩的,jackson 也是挺辛苦 为了方便大家提供了各种奇葩姿势的支持。

最后吐槽下 不是说 lz ,普遍现象,现在写 java 的人是真多,title 越高,代码越烂,反正不影响业务跑就行(影响了只要人人能跑也行)
weofuh
2022-11-21 15:48:50 +08:00
@urnoob 哈哈哈,上午 debug 了下,没搞懂为啥要 merge 进 map 的 list 里去,是有什么规范或者约定啥的。提供类似 getCopyList 这样方法的同事可能是方便在其他地方使用的时候不需要关心 map 里的 key 是什么吧,因为我看到了好几个类似的 get 方法。
JYii
2022-11-21 15:59:50 +08:00
一开始还没出来, debug 进去发现怎么有个 CopyList, 已经想开喷了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/896796

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX