如何 serialize/deserialize 反对映射
How to serialize/deserialize object to Map
我有一个具体案例。我需要 serialize/deserialize 一个对象到 Map<String, Object>
。我有一个如下所示的 class:
public class Data {
public String name;
public Map<String, Object> options = new HashMap<>();
}
我可以将任何类型的对象放入此选项。例如:
public class Option {
public int id;
...
}
public class TestOpt {
public name;
...
}
然后我尝试对其进行序列化和反序列化:
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);
}
我该如何解决这个问题?
序列化后的值json
为
{"name":"data","options":{"t":{"name":"fff"},"o":{"id":1}}}
所以,问题是对象映射器无法判断 json 中的 o
值是一个 Option
。最好的猜测是它可能是一张地图,因此它被反序列化为 LinkedHashMap
.
如果您确定元素 o
是一个 Option
,您可以使用对象映射器转换该值:
Option option = mapper.convertValue(d1.options.get("o"), Option.class);
但请注意,这意味着该值将再次序列化,然后使用正确的类型信息进行反序列化。你可以这样做,但这不是一个好的解决方案。
如果可能,更好的方法是将您的模型从通用映射更改为包含类型信息的特定 class:
class Data {
public String name;
public DataOptions options = new DataOptions();
}
class DataOptions {
public Option o;
public TestOpt t;
}
序列化此模型与使用地图的模型具有相同的 json 表示,并且该模型可用于反序列化示例中的 json。
我有一个具体案例。我需要 serialize/deserialize 一个对象到 Map<String, Object>
。我有一个如下所示的 class:
public class Data {
public String name;
public Map<String, Object> options = new HashMap<>();
}
我可以将任何类型的对象放入此选项。例如:
public class Option {
public int id;
...
}
public class TestOpt {
public name;
...
}
然后我尝试对其进行序列化和反序列化:
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);
}
我该如何解决这个问题?
序列化后的值json
为
{"name":"data","options":{"t":{"name":"fff"},"o":{"id":1}}}
所以,问题是对象映射器无法判断 json 中的 o
值是一个 Option
。最好的猜测是它可能是一张地图,因此它被反序列化为 LinkedHashMap
.
如果您确定元素 o
是一个 Option
,您可以使用对象映射器转换该值:
Option option = mapper.convertValue(d1.options.get("o"), Option.class);
但请注意,这意味着该值将再次序列化,然后使用正确的类型信息进行反序列化。你可以这样做,但这不是一个好的解决方案。
如果可能,更好的方法是将您的模型从通用映射更改为包含类型信息的特定 class:
class Data {
public String name;
public DataOptions options = new DataOptions();
}
class DataOptions {
public Option o;
public TestOpt t;
}
序列化此模型与使用地图的模型具有相同的 json 表示,并且该模型可用于反序列化示例中的 json。