简体   繁体   English

在Jackson中反序列化对象引用

[英]Deserialize object reference in Jackson

I am trying to deserialize a object ref ($ref) using ObjectMapper. 我试图使用ObjectMapper反序列化对象ref($ 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 This is the json file I am trying to deserialize. test.json这是我试图反序列化的json文件。 Is this is the correct way to refer to a object/json reference? 这是引用对象/ json引用的正确方法吗?

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

Deserializer.java Deserializer.java

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

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

the result creates a Foo pojo with additional property of "bar": ""$ref": "/bar.json"" rather than deserializing it. 结果创建了一个带有“bar”附加属性的Foo pojo:“”$ ref“:”/ bar.json“”而不是反序列化它。 Do I need to implement the deserialize interface and manually deserialize the node? 我是否需要实现反序列化接口并手动反序列化节点?

Traditionally in Comp Sc. 传统上在Comp Sc。 this problem is solved using what is known as "Pointer Swizzling". 使用所谓的“Pointer Swizzling”解决了这个问题。

This means that If you have an Object A that contains a reference to B and you want to serialize this structure (and then deserialize it), you would need to "unswizzle" the pointer to B to a "name" (an identifier that uniquely identifies the instance B) , write it to disk. 这意味着如果你有一个包含对B的引用的对象A并且你想要序列化这个结构(然后反序列化它),你需要将指向B的指针“取消”到“名称”(唯一的标识符)标识实例B),将其写入磁盘。 When deserializing, you would then take that name, find the instance that it points to (B) and "swizzle" the name back to a proper pointer to B. 在反序列化时,您将获取该名称,找到它指向的实例(B)并将该名称“混合”回到指向B的正确指针。

Now, in Java pointers are called references but it's the same. 现在,在Java中,指针被称为引用,但它们是相同的。

Here's an example to illustrate: 这是一个例子来说明:

originalA = { "id":"id_a", "ref_to_b": originalB}
originalB = { "id":"id_b" }

Applying unswizzling: 申请未破坏:

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

followed by writing to store/reading back from store. 然后写入商店/从商店回读。

Applying swizzling: 应用swizzling:

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

One possible way to do it for your case,is to deserialize all objects first, put them into an HashMap and in a second pass, look up the ObjectReference(s) from the various ObjectID(s) that you have in your JSON (swizzling). 为你的情况做一个可能的方法是首先反序列化所有对象,将它们放入HashMap,然后在第二遍中,从你在JSON中的各种ObjectID中查找ObjectReference(swizzling) )。

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

You need to store {"$ref": "/bar.json"} this as a Map. 您需要将{"$ref": "/bar.json"}为地图。 That's the simplest way to store it. 这是存储它的最简单方法。

Example: 例:

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;
    }
}

Only then it will get the value of $ref in Bar object. 只有这样它才能在Bar对象中获得$ ref的值。 Otherwise, the data will be in incorrect format and Bar object will take the entire bar value into it. 否则,数据格式将不正确,Bar对象将整个条形值输入其中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM