我有一个需要序列化为XML的类的小层次结构。我发现了一个过去的帖子(Jackson序列化列表,其中包含XML的多态元素),它对于让子类使用正确的子类名称序列化很有用。但是,这些子类的字段没有被序列化。这里我将提供一个示例:
public abstract class Animal {}
public class Dog extends Animal{
public String breed;
public String age;
public Dog(String breed, String age) {
this.breed = breed;
this.age = age;
}
}
@JsonSerialize(using = ZooSerializer.class)
public class Zoo {
public List<Animal> animals = new ArrayList<>();
}
public class ZooSerializer extends StdSerializer<Zoo> {
public ZooSerializer(Class<Zoo> t) {
super(t);
}
public ZooSerializer() {
this(null);
}
@Override
public void serialize(Zoo zoo, JsonGenerator jg, SerializerProvider sp) throws IOException
{
jg.writeStartObject();
for (Animal animal: zoo.animals) {
jg.writeNullField(animal.getClass().getSimpleName());
}
jg.writeEndObject();
}
,然后用这个来测试:
@Test
public void Test() {
XmlMapper xmlMapper = new XmlMapper();
try {
Zoo zoo = new Zoo();
Dog dog = new Dog("Collie", "6");
System.out.println(xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(dog));
zoo.animals.add(dog);
System.out.println(xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(zoo));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
,我得到以下回应:
<Dog>
<breed>Collie</breed>
<age>6</age>
</Dog>
<Zoo>
<Dog/>
</Zoo>
因此,我无法理解为什么在单独流式传输狗对象时会出现狗场,而在添加到动物园对象后流式传输时不会出现狗场。如果有任何想法,我将不胜感激。非常感谢。
您可以使用< code > JSON generator # writeObjectField 方法来序列化已经定义的< code > zoo serializer # serialize 方法中的< code>Dog pojo,如下所示:
public class ZooSerializer extends StdSerializer<Zoo> {
public ZooSerializer(Class<Zoo> t) {
super(t);
}
public ZooSerializer() {
this(null);
}
@Override
public void serialize(Zoo zoo, JsonGenerator jg, SerializerProvider sp) throws IOException {
jg.writeStartObject();
for (Animal animal: zoo.animals) {
String animalClassName = animal.getClass().getSimpleName();
jg.writeObjectField(animalClassName, animal);
}
jg.writeEndObject();
}
}
Output in your main example:
<Zoo>
<Dog>
<breed>Collie</breed>
<age>6</age>
</Dog>
</Zoo>
由于以这种方式编写自定义序列化程序而不使用JsonTypeInfo
,如果要将获得的xml反序列化为Zoo
对象,则必须编写自定义反序列化程序。