简体   繁体   中英

Deserialize object reference in Jackson

I am trying to deserialize a object ref ($ref) using ObjectMapper.

 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. Is this is the correct way to refer to a object/json reference?

{  
  "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);

the result creates a Foo pojo with additional property of "bar": ""$ref": "/bar.json"" rather than deserializing it. Do I need to implement the deserialize interface and manually deserialize the node?

Traditionally in Comp Sc. this problem is solved using what is known as "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. 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.

Now, in Java pointers are called references but it's the same.

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:

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).

Some further reading: https://en.wikipedia.org/wiki/Pointer_swizzling

You need to store {"$ref": "/bar.json"} this as a Map. 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. Otherwise, the data will be in incorrect format and Bar object will take the entire bar value into it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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