java - JAXB 和抽象类

标签 java xml xml-serialization jaxb

我正在尝试使用 JAXB 解码某些 XML,但我收到“无法创建...的实例”异常。我明白为什么——它试图创建一个抽象类的实例。我想要的是让它成为特定实现类的实例。我的目标是对 setter 方法进行特定于类的检查。也许“qux”是 BarImpl 的有效 baz 值,但 BarImpl2 想要做其他事情。

我通过不注释 Foo 完成了部分工作,但如果我取消注释 bar,事情就会变得很糟糕。

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.junit.Test;


public class JAXBTest {

    @Test
    public void test() throws javax.xml.bind.JAXBException {
        String xml = 
            "<foo>" +
            "  <bar>" +
            "    <baz>qux</baz>" +
            "  </bar>" +
            "</foo>";

        javax.xml.bind.JAXBContext context = javax.xml.bind.JAXBContext.newInstance(
                FooImpl.class,
                BarImpl.class
        );

        javax.xml.bind.Unmarshaller unmarshaller = context.createUnmarshaller();

        unmarshaller.unmarshal(new java.io.StringReader(xml));
    }

    @XmlRootElement(name="foo")
    public static abstract class Foo {
        @XmlElement(name="bar")
        Bar bar;
    }

    @XmlRootElement(name="bar")
    public static abstract class Bar {
        @XmlElement(name="baz")
        String baz;
    }

    public static class FooImpl extends Foo { }
    public static class BarImpl extends Bar { }
}

最佳答案

您可以执行以下操作:

JAXB测试

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

import org.junit.Test;


public class JAXBTest {

    @Test
    public void test() throws javax.xml.bind.JAXBException {
        String xml = 
            "<foo>" +
            "  <bar>" +
            "    <baz>qux</baz>" +
            "  </bar>" +
            "</foo>";

        javax.xml.bind.JAXBContext context = javax.xml.bind.JAXBContext.newInstance(
                FooImpl.class,
                BarImpl.class
        );

        javax.xml.bind.Unmarshaller unmarshaller = context.createUnmarshaller();

        unmarshaller.unmarshal(new java.io.StringReader(xml));
    }

    @XmlTransient
    public static abstract class Foo {
        @XmlElements({
            @XmlElement(name="bar",type=BarImpl.class),
            @XmlElement(name="bar",type=BarImpl2.class),
        })
        Bar bar;
    }

    @XmlTransient
    public static abstract class Bar {
        @XmlElement(name="baz")
        String baz;
    }

    @XmlRootElement(name="foo")
    public static class FooImpl extends Foo { }

    @XmlRootElement(name="bar")
    public static class BarImpl extends Bar { }

    public static class BarImpl2 extends Bar { }
}

关于java - JAXB 和抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9580028/

相关文章:

java - 没有 Spring Boot 的 Spring Data JPA

C# xml序列化

asp.net - XML 序列化使用的 PropertySpecified 模式的目的是什么?

java - GWT,修改使用InputStreamReader和java.net.URL类通过Post发送HashMap或其他对象的代码?

java - 图形数组列表

javafx.builders 包的 JavaFX 导入错误

java - 重新绘制一个 argb BufferedImage

java - 如何动态地将布局和 View 添加到 Android XML 布局文件?

java - 使用 Java SE 删除 XML 节点

c# - 反序列化根为列表的 XML 文档