在Jackson中反序列化对象引用

时间:2017-03-10 08:24:59

标签: java json jackson deserialization objectmapper

我正在尝试使用ObjectMapper反序列化对象引用($ ref)。

 public class Foo {
    @JsonProperty("bar")
    private Bar bar;

    @JsonProperty("bar")
    public Bar getBar() {
        return bar;
    }

    @JsonProperty("bar")
    public void setBar(Bar bar) {
        this.bar = bar;
    }
}

test.json 这是我试图反序列化的json文件。 这是引用object / json引用的正确方法吗?

{  
  "bar": {"$ref": "/bar.json"}
}

Deserializer.java

ObjectMapper objectMapper = new ObjectMapper();
//load class
URL url = Deserializer.class.getClassLoader().getResource("test.json");

//deserialize 
objectMapper.readValue(url, Foo.class);

结果创建了一个带有“bar”附加属性的Foo pojo:“”$ ref“:”/ bar.json“”而不是反序列化它。我是否需要实现反序列化接口并手动反序列化节点?

2 个答案:

答案 0 :(得分:1)

传统上在Comp Sc。使用所谓的" Pointer Swizzling"解决了这个问题。

这意味着如果你有一个包含对B的引用的对象A并且你想序列化这个结构(然后反序列化它),你需要" unswizzle"指向B的指针" name" (唯一标识实例B的标识符),将其写入磁盘。反序列化时,您将获取该名称,找到它指向的实例(B)和" swizzle"该名称返回指向B的正确指针。

现在,在Java中,指针被称为引用,但它们是相同的。

以下是一个例子:

readyForSerializationA = { "id":"id_a", "ref_to_b": "id_b"}
readyForSerializationB = { "id": "id_b" }

申请未破坏:

deserializedB = { "id":"id_b" }
deserializedA = { "id": "id_a", "ref_to_b": deserializedB}

然后写入商店/从商店回读。

应用swizzling:

{{1}}

为您的案例执行此操作的一种可能方法是首先对所有对象进行反序列化,将它们放入HashMap中,然后在第二次传递中,从您在其中的各种ObjectID中查找ObjectReference(s)。 JSON(调情)。

进一步阅读:https://en.wikipedia.org/wiki/Pointer_swizzling

答案 1 :(得分:0)

您需要将{"$ref": "/bar.json"}存储为地图。这是存储它的最简单方法。

示例:

public class Foo {
    @JsonProperty("bar")
    private Map<String, Bar> bar;

    @JsonProperty("bar")
    public Map<String, Bar> getBar() {
        return bar.get("$ref");
    }

    @JsonProperty("bar")
    public void setBar(Map<String, Bar> bar) {
        this.bar = bar;
    }
}

只有这样它才能在Bar对象中获得$ ref的值。否则,数据的格式将不正确,Bar对象将把整个条形值输入其中。