我目前正在尝试序列化对象树并在之后对其进行反序列化,以便所有引用保持不变。问题是,持有这些引用的字段是Object类型。以下代码段
public class Main {
public static void main(String[] args) throws IOException {
Root r = new Root();
Element e = new Element();
e.s = "test";
r.o1 = e;
r.o2 = e;
ObjectMapper ma = new ObjectMapper();
ma.addMixInAnnotations(Object.class, Mixin.class);
String json = ma.writeValueAsString(r);
System.out.println(json);
Root r2 = ma.readValue(json, Root.class);
System.out.println(r2.o1.getClass());
System.out.println(r2.o2.getClass());
System.out.println(r2.o1 == r2.o2);
}
public static class Root {
public Object o1;
public Object o2;
}
public static class Element {
public String s;
}
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id")
public static class Mixin {
}
}
产生以下输出:
{"@class":"Main$Root","@id":1,"o1":{"@class":"Main$Element","@id":2,"s":"test"},"o2":2}
Main$Element
java.lang.Integer
false
元素的第一次出现'正确反序列化,因为它附加了类型信息。然而,第二个不是,因为当仅序列化id时不添加类型信息。 id被反序列化为Integer,因为解析器不会将其识别为id,因为该字段的类型为' Object'。
所以问题是:有没有办法告诉杰克逊附加类型信息,即使只写了id,以便反序列化的元素'是一样的吗?
编辑:类型必须是Object,因为在我的用例中,内容几乎可以是任何内容,甚至是我无法控制的类。所以主要问题是如何在引用本身中包含类型信息。
感谢您的时间。
答案 0 :(得分:0)
好的,我想我已经弄明白了。
当使用@JsonTypeInfo
时,杰克逊尝试在 SAME 对象作为已经序列化的对象时缩写对象。在这种情况下,它不包括数据,而是仅包括对先前序列化对象的引用。这是有道理的。
但出于某种原因,使用Object
元素中的Root' object doesn't carry the identity and things break from there. If you create a dummy interface, use that as your base type, drop the MixIn on it and have
来实现它,一切都会成功。
这是我最终的结果:
public static void main(String[] args) throws IOException {
Root r = new Root();
Element e = new Element();
e.s = "test1";
r.o1 = e;
r.o2 = e;
ObjectMapper ma = new ObjectMapper();
ma.addMixInAnnotations(Root.class, Mixin.class);
ma.addMixInAnnotations(Base.class, Mixin.class);
String json = ma.writeValueAsString(r);
System.out.println(json);
Root r2 = ma.readValue(json, Root.class);
System.out.println(r2.o1.getClass());
System.out.println(r2.o2.getClass());
System.out.println(r2.o1 == r2.o2);
}
public static class Root {
public Base o1;
public Base o2;
}
public interface Base {
}
public static class Element implements Base {
public String s;
}
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id")
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
public static class Mixin {
}
这会得到以下输出:
{"@class":"Main$Root","@id":1,"o1":{"@class":"Main$Element","@id":2,"s":"test1"},"o2":2}
class Main$Element
class Main$Element
true
用Jackson 2.3.3进行了这项测试