JAXB:反序列化扩展A类的B类的问题

Rob*_*ert 6 java constructor jaxb adapter unmarshalling

请考虑以下示例:

有一个ClassA和一个ClassB扩展它.我现在的问题是我必须从xml文件解组ClassB.请注意,ClassA不能更改,因为它不在我的控制之下.

在此示例中注意到几个问题:

主要问题是ClassA没有默认的no-arg构造函数,这是JAXB在没有Adapter的情况下所需的.因此,我实现MyAdapter它映射ClassB的到简单的类值Valb其可以通过JAXB没有任何问题地处理.

主要问题是如何让JAXB使用这个适配器?既不在类级别定义 @XmlJavaTypeAdapter也不在unmarshaller中注册适配器.

有没有人知道如何使JAXB使用MyAdapter,以便unmarshaller返回一个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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句:不要把代码太严肃 - 这只是一个证明问题的例子.我知道ClassAClassB的定义并不真正有用.

bdo*_*han 2

更新

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

从 12 月 18 日开始,可以在此处获取包含此修复程序的预发行版本:

解决方法

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

@XmlTransient
public static abstract class ClassA {
    public ClassA(String id) {
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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