我有一个带有< code >列表的< code>Zoo类型
例如:
abstract class Animal {}
@JacksonXmlRootElement(localName = "Dog")
class Dog extends Animal {}
@JacksonXmlRootElement(localName = "Cat")
class Cat extends Animal {}
@JacksonXmlRootElement(localName = "Zoo")
public class Zoo {
@JacksonXmlProperty
@JacksonXmlElementWrapper(useWrapping = false)
List<Animal> animals = new ArrayList<>();
}
序列化 Zoo
实例。
public static void main(String[] args) throws JsonProcessingException {
Zoo zoo = new Zoo();
zoo.animals.add(new Dog());
zoo.animals.add(new Cat());
zoo.animals.add(new Dog());
String xml = new XmlMapper().writerWithDefaultPrettyPrinter()
.writeValueAsString(zoo);
System.out.println(xml);
}
我希望得到:
<Zoo>
<Dog/>
<Cat/>
<Dog/>
</Zoo>
实际输出:
<Zoo>
<animals/>
<animals/>
<animals/>
</Zoo>
使用自定义序列化器可以获得预期的结果,但使用JsonTypeInfo
会失去所有可用的优势,并且还必须编写自定义反序列化器。无论如何,您可以定义三个简单的类,如下所示:
public abstract class Animal {}
public class Dog extends Animal {}
@JsonSerialize(using = ZooSerializer.class)
public class Zoo {
List<Animal> animals = new ArrayList<>();
}
然后你必须编写你的自定义ZooSerializer
序列化器来构建你的自定义xml:
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();
}
}
这将产生预期的结果,但代价是失去所有优点,因为自动序列化和反序列化可以通过对两个类使用< code>JsonTypeInfo和< code>JsonSubTypes批注来获得:
Zoo zoo = new Zoo();
zoo.animals.add(new Dog());
zoo.animals.add(new Dog());
/* the str content obtained by the serialization of zoo
Zoo>
<Dog/>
<Dog/>
</Zoo>
*/
String str = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(zoo);