You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 10:43:22