简体   繁体   中英

How to serialize/deserialize object to Map

I have one specific case. I need to serialize/deserialize an object to Map<String, Object> . I have a class that looks like the following:

public class Data {
    public String name;
    public Map<String, Object> options = new HashMap<>();
}

I can put to this options objects of any type. For instance:

public class Option {
    public int id;
    ...
}

public class TestOpt {
    public name;
    ...
}

and I try to serialize and deserialize it:

public static void main(String... args) {
    ObjectMapper mapper = new ObjectMapper();
    Option o = new Option();
    o.id = 1;
    TestOpt t = new TestOpt();
    t.name = "fff";
    Data data = new Data();
    data.name = "data";
    data.options.put("o", o);
    data.options.put("t", t);
    String json = mapper.writeValueAsString(data);

    Data d1 = mapper.readValue(json, Data.class);
    // I get error because options.get("o") contains LinkedHashMap instead of Option.class
    System.out.println(((Option)d1.options.get("o")).id);
}

How can I fix this issue?

The value of the serialized json is

{"name":"data","options":{"t":{"name":"fff"},"o":{"id":1}}}

So, the problem is that the object mapper has no way to tell that the o value inside the json is an Option . The best guess is that it could be a map and thus it is deserialized as a LinkedHashMap .

If you are sure that the element o is an Option , you can convert the value using an object mapper:

Option option = mapper.convertValue(d1.options.get("o"), Option.class);

But please note, that this means that the value is again serialized and then deserialized using the right type information. You can do that, but it is not a good solution.

If it is possible, a better way would be to change your model from a generic map to a specific class that contains the type information:

class Data {
    public String name;
    public DataOptions options = new DataOptions();
}

class DataOptions {
    public Option o;
    public TestOpt t;
}

Serializing this model has the same json representation as the model using a map, and the model can be used to deserialize the json from your example.

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