Java 使用jaxb时使用派生类

Java 使用jaxb时使用派生类,java,jaxb,Java,Jaxb,我有一个带有公共基类的对象列表,我正试图使用jaxb将其序列化为XML。我希望在编组时使用派生类的注释,但是我很难做到这一点 import java.util.Arrays; import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.annotation

我有一个带有公共基类的对象列表,我正试图使用jaxb将其序列化为XML。我希望在编组时使用派生类的注释,但是我很难做到这一点

import java.util.Arrays;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlRootElement;


public class Runner {
    @XmlRootElement(name="base")
    public static abstract class Base {
        public int baseValue;

        public Base() {
            this.baseValue = 0;
        }
    }

    @XmlRootElement(name="derived")
    public static class Derived extends Base {
        public int derivedValue;

        public Derived() {
            super();
            this.derivedValue = 1;
        }
    }

    @XmlRootElement(name="derived2")
    public static class Derived2 extends Base {
        public int derivedValue;

        public Derived() {
            super();
            this.derivedValue = 1;
        }
    }

    @XmlRootElement(name="base_list")
    public static class BaseList {
        public List<Base> baseList;
    }

    public static void main(String[] args) throws JAXBException {
        BaseList baseList = new BaseList();
        baseList.baseList = Arrays.asList((Base) new Derived(), (Base) new Derived());

        JAXBContext jaxbContext = JAXBContext.newInstance(BaseList.class);

        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
        marshaller.marshal(baseList, System.out);

    }
}
导入java.util.array;
导入java.util.List;
导入javax.xml.bind.JAXBContext;
导入javax.xml.bind.JAXBException;
导入javax.xml.bind.Marshaller;
导入javax.xml.bind.annotation.XmlRootElement;
公开课跑者{
@XmlRootElement(name=“base”)
公共静态抽象类库{
公共价值;
公共基地(){
此.baseValue=0;
}
}
@XmlRootElement(name=“派生”)
公共静态类派生的扩展基{
公共价值;
公共派生(){
超级();
此.derivedValue=1;
}
}
@XmlRootElement(name=“derived2”)
公共静态类Derived2扩展了基{
公共价值;
公共派生(){
超级();
此.derivedValue=1;
}
}
@XmlRootElement(name=“基本列表”)
公共静态类基列表{
公共清单基础清单;
}
公共静态void main(字符串[]args)抛出JAXBEException{
BaseList BaseList=新的BaseList();
baseList.baseList=Arrays.asList((Base)new-Derived(),(Base)new-Derived());
JAXBContext JAXBContext=JAXBContext.newInstance(BaseList.class);
Marshaller=jaxbContext.createMarshaller();
setProperty(marshaller.JAXB_格式化的_输出,true);
setProperty(marshaller.JAXB_片段,true);
marshaller.marshall(基本列表,系统输出);
}
}
我想:

<base_list>
    <derived>
        <baseValue>0</baseValue>
        <derivedValue>1</derivedValue>
    </derived>
    <derived2>
        <baseValue>0</baseValue>
        <derivedValue>1</derivedValue>
    </derived2>
</base_list>

0
1.
0
1.
然而,上述代码给出了:

<base_list>
    <baseList>
        <baseValue>0</baseValue>
    </baseList>
    <baseList>
        <baseValue>0</baseValue>
    </baseList>
</base_list>

0
0
有没有办法强迫它使用派生类?在实际情况中,我并不提前知道可能从Base派生的类


请注意,我只需要封送,而不是解封数据。

您可以使用
@xmlementref
注释来处理此用例
@xmlementref
对应于XML模式中的替换组概念

例如:


这是可行的,但我似乎需要提供一个从Base到jaxb上下文的类列表。在实际情况下,我在编译时并没有可能的派生类的列表。@ICR-您也可以尝试使用
@xmlanyement(lax=true)
:这仍然需要向jaxb上下文对象注册派生类。我想我可以为新模块添加一种方法来注册它们的派生对象,然后将其传递到JAXBContext中。@ICR-我领导了EcliseLink JAXB(MOXy)实现,并且我们提供了一个扩展,可以让您添加新模块:除了
@xmlementref
,我不得不添加带有派生类的
@xmlsee注释。