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)
顺便说一句:不要把代码太严肃 - 这只是一个证明问题的例子.我知道ClassA和ClassB的定义并不真正有用.
更新
我们已在即将发布的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的文章:
| 归档时间: |
|
| 查看次数: |
2098 次 |
| 最近记录: |