像Jackson这样的JAXB多态类型对象编组

时间:2013-10-19 11:42:21

标签: java jaxb jackson

我使用Jackson在祖先类中使用注释为多态对象创建JSON:

// Include Java class name ("com.myempl.ImplClass") as JSON property "class"
@JsonTypeInfo(use=Id.CLASS, include=As.PROPERTY, property="class")

使用此批注,后代类将具有class属性以及对象的类名。当Jackson将JSON对象转换回正确的后代时,将使用此类名。

将JAX-B与

一起使用时
@XmlSeeAlso({Class1, Class2, ... ClassN })

注释,如果要进行正确的解组,则必须指定元素的所有子类,或者在创建新的JAXBContext实例时应将所有元素添加到JAXBContext

有没有办法像杰克逊一样为JAX-B指定对象类名? 如果没办法,为什么?

1 个答案:

答案 0 :(得分:1)

我相信您正在寻找@XmlType注释。以下是如何使用它的示例:

Java模型

<强>根

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Root {

    private List<AbstractClass> classes = new ArrayList<AbstractClass>();

    @XmlElement(name="class")
    public List<AbstractClass> getClasses() {
        return classes;
    }

}

<强> AbstactClass

我们将使用@XmlSeeAlso注释来在计算元数据时处理Class1Class2。 Java没有提供反射访问类的子类的机制。

import javax.xml.bind.annotation.XmlSeeAlso;

@XmlSeeAlso({Class1.class, Class2.class})
public class AbstractClass {

}

<强>的Class1

默认情况下,每个类都有一个为短类名派生的类指示符名称。

public class Class1 extends AbstractClass {

}

<强>的Class2

我们可以使用@XmlType注释来覆盖类指示符名称。

import javax.xml.bind.annotation.XmlType;

@XmlType(name="class-two")
public class Class2 extends AbstractClass {

}

演示代码

<强>演示

下面我们将创建Root的实例,并在Class1属性上设置Class2classes的实例,该属性属于超类型AbstractClass

import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Root root = new Root();
        root.getClasses().add(new Class1());
        root.getClasses().add(new Class2());

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

<强>输出

xsi:type实例的Class1的值是从类名派生的,而Class2实例的值对应于我们在{{@XmlType上设置的名称。 1}}注释。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <class xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="class1"/>
    <class xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="class-two"/>
</root>