如何使用Jackson XML根据属性的类类型动态修改XML标签?
用Jackson XML实现根据子类类型动态生成XML标签
要实现根据pet属性的实际类型(Dog/Cat)生成对应的<dog>/<cat>标签,核心是利用Jackson的类型信息注解控制序列化时的标签名称,具体步骤如下:
1. 给父类Animal添加类型注解
通过@JsonTypeInfo和@JsonSubTypes注解,指定子类对应的XML标签名称:
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT) @JsonSubTypes({ @JsonSubTypes.Type(value = Dog.class, name = "dog"), @JsonSubTypes.Type(value = Cat.class, name = "cat") }) public class Animal { private String name; // 必须提供无参构造(Jackson序列化需要) public Animal() {} public Animal(String name) { this.name = name; } // getter/setter public String getName() { return name; } public void setName(String name) { this.name = name; } }
2. 完善子类Dog和Cat
确保子类提供无参构造方法,同时继承父类的属性:
public class Dog extends Animal { public Dog() {} public Dog(String name) { super(name); } } public class Cat extends Animal { public Cat() {} public Cat(String name) { super(name); } }
3. 保持Person类不变
Person类无需额外注解,只要正确提供属性的getter/setter和无参构造即可:
public class Person { private String name; private Animal pet; public Person() {} public Person(String name) { this.name = name; } // getter/setter public String getName() { return name; } public void setName(String name) { this.name = name; } public Animal getPet() { return pet; } public void setPet(Animal pet) { this.pet = pet; } }
4. 测试序列化代码
使用XmlMapper进行序列化,开启格式化输出让XML更易读:
import com.fasterxml.jackson.dataformat.xml.XmlMapper; public class TestSerialization { public static void main(String[] args) throws Exception { XmlMapper xmlMapper = new XmlMapper(); Person p1 = new Person("P1"); p1.setPet(new Dog("Pluto")); System.out.println(xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(p1)); Person p2 = new Person("P2"); p2.setPet(new Cat("Tom")); System.out.println(xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(p2)); } }
原理说明
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT):告诉Jackson用子类的名称作为包装对象的标签,也就是XML中的外层节点。@JsonSubTypes:显式指定每个子类对应的名称(dog/cat),序列化时会自动替换成对应的XML标签。- 无参构造的必要性:Jackson在处理对象序列化/反序列化时,需要通过无参构造实例化对象,因此所有实体类都必须提供。
运行后就能得到期望的XML输出:
<person> <name>P1</name> <dog> <name>Pluto</name> </dog> </person> <person> <name>P2</name> <cat> <name>Tom</name> </cat> </person>
内容的提问来源于stack exchange,提问作者marciel.deg
相关产品推荐
相关产品推荐

