如何用Jackson将含多态元素的List序列化为带不同标签的XML?
Jackson XML序列化:为集合中子类对象生成自定义标签名
我有一个Zoo类,包含List<Animal>字段,元素是Animal的子类对象。使用Jackson序列化Zoo为XML时,希望不同子类对应不同的标签名,但当前输出统一用animals标签,不符合预期。
现有代码
实体类代码
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<>(); }
序列化代码
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>
解决方案
要让Jackson识别子类并生成对应标签,需要在父类Animal上添加类型识别注解,同时调整相关配置:
修改后的实体类代码
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; // 配置类型信息:用名称作为XML标签 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_ELEMENT) // 声明子类与标签名的对应关系 @JsonSubTypes({ @JsonSubTypes.Type(value = Dog.class, name = "Dog"), @JsonSubTypes.Type(value = Cat.class, name = "Cat") }) abstract class Animal {} class Dog extends Animal {} class Cat extends Animal {} @JacksonXmlRootElement(localName = "Zoo") public class Zoo { // 移除@JacksonXmlProperty,避免字段名覆盖子类标签名 @JacksonXmlElementWrapper(useWrapping = false) List<Animal> animals = new ArrayList<>(); }
原理说明
@JsonTypeInfo指定Jackson如何识别子类类型,这里设置为用自定义名称作为XML标签(WRAPPER_ELEMENT表示直接用该名称作为元素标签)。@JsonSubTypes明确绑定每个子类对应的XML标签名称。- 移除
Zoo类中animals字段的@JacksonXmlProperty,避免字段名animals干扰子类标签的生成。
修改后运行序列化代码,即可得到符合预期的XML输出。
内容的提问来源于stack exchange,提问作者robothy
相关产品推荐
相关产品推荐

