6

请考虑以下示例:

有一个ClassA和一个ClassB扩展它。我现在的问题是我必须从 xml 文件中解组 ClassB 。请注意,ClassA无法更改,因为它不受我的控制。

在这个例子中注意到了几个问题:

主要问题是ClassA没有没有适配器的 JAXB 所需的默认无参数构造函数。因此,我实现了 MyAdapter ,它将ClassB映射到简单的类ValB,它可以由 JAXB 处理而没有任何问题。

主要问题是如何让 JAXB 使用这个适配器?既没有在类级别定义 @XmlJavaTypeAdapter也没有将适配器注册到解组器。

有谁知道如何让 JAXB 使用MyAdapter以便解组器返回一个作为ClassA实例的对象?

public class JaxbTest {

    public static abstract class ClassA {
        public ClassA(String id) {
        }
    }

    @XmlRootElement
    @XmlJavaTypeAdapter(MyAdapter.class) // does not have an effect
    public static class ClassB extends ClassA {

        public String text;

        public ClassB() {
            super("");
        }
    }

    public static class ValB {
        public String text;
    }

    public static class MyAdapter extends XmlAdapter<ValB, ClassB> {

        @Override
        public ClassB unmarshal(ValB v) throws Exception {
            ClassB b = new ClassB();
            b.text = v.text;
            return b;
        }

        @Override
        public ValB marshal(ClassB v) throws Exception {
            ValB b = new ValB();
            b.text = v.text;
            return b;
        }

    }

    public static void main(String[] args) {
        try {
            JAXBContext context = JAXBContext.newInstance(ClassB.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            unmarshaller.setAdapter(new MyAdapter()); // does not have an effect
            ClassA a = (ClassA) unmarshaller.unmarshal(new File("test.xml"));
            // do somthing with a
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

顺便说一句:不要把代码看得太严肃——这只是一个展示问题的例子。我知道ClassAClassB的定义并不是很有用。

4

1 回答 1

2

更新

我们已经在即将发布的EclipseLink JAXB (MOXy) 2.2.0 版本中解决了这个问题(请参阅错误 #332742)。在此版本中,将不会检查抽象类的无参数构造函数。

从 12 月 18 日开始,可以在此处获得具有此修复的预发布版本:

解决方法

这就是 @XmlTransient 注释的用途。如果可能,请执行以下操作:

@XmlTransient
public static abstract class ClassA {
    public ClassA(String id) {
    }
}

如果无法直接注释 ClassA,您可以利用EclipseLink JAXB (MOXy)扩展来执行此操作。MOXy 允许您将 JAXB 元数据指定为 XML 文件。当您无法修改模型类时,这很有用:

下面是一些解释@XmlAdapter 的文章:

于 2010-12-16T10:35:37.683 回答