[英]Determine subclass when unmarshalling with JAXB
我将尝试提供我的问题的SSCCE。
我有这个类的层次结构:
班级基础:
@XmlRootElement
@XmlSeeAlso({ A.class, B.class })
@XmlAccessorType(XmlAccessType.FIELD)
public class Base {
@XmlAttribute
private String baseData;
public String getBaseData() {
return baseData;
}
public void setBaseData(String baseData) {
this.baseData = baseData;
}
}
A级扩展基础
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="A", propOrder = { "dataA1", "dataA2" })
@XmlRootElement(name = "Base", namespace = "")
public class A extends Base {
private String dataA1;
private String dataA2;
public String getDataA1() {
return dataA1;
}
public void setDataA1(String dataA1) {
this.dataA1 = dataA1;
}
public String getDataA2() {
return dataA2;
}
public void setDataA2(String dataA2) {
this.dataA2 = dataA2;
}
}
B类扩展了基础
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="B", propOrder = { "dataB1", "dataB2" })
@XmlRootElement(name = "Base", namespace = "")
public class B extends Base {
private String dataB1;
private String dataB2;
public String getDataB1() {
return dataB1;
}
public void setDataB1(String dataB1) {
this.dataB1 = dataB1;
}
public String getDataB2() {
return dataB2;
}
public void setDataB2(String dataB2) {
this.dataB2 = dataB2;
}
}
但是当我尝试测试时:
public class Test {
public static void main(String[] args) throws Exception {
Base base = new A();
base.setBaseData("BaseDataA");
((A) base).setDataA1("DataA1");
((A) base).setDataA2("DataA2");
JAXBContext jc = JAXBContext.newInstance(Base.class, A.class, B.class);
// Marshal the object
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter sw = new StringWriter();
marshaller.marshal(base, sw);
// Unmarshal the object
Unmarshaller unmarshaller = jc.createUnmarshaller();
String generatedXml = sw.toString();
System.out.println(generatedXml);
Base objectFromUnmarshall = (Base) unmarshaller.unmarshal(new StringReader(generatedXml));
System.out.println(objectFromUnmarshall);
// Re-marshal the object
System.out.println("");
sw = new StringWriter();
marshaller.marshal(objectFromUnmarshall, sw);
System.out.println(sw.toString());
}
}
这是输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Base baseData="BaseDataA">
<dataA1>DataA1</dataA1>
<dataA2>DataA2</dataA2>
</Base>
jaxb.B@5c0369c4
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Base baseData="BaseDataA"/>
我将对象A行进,但在解组时会创建B的实例!
为什么? 我怎样才能告诉他解散好榜样?
注意:我正在使用Sun JAXB实现,无法更改它。
好吧,我发现处理它的唯一方法是使用XMLAdapter(基于这篇很棒的文章 )。
public class BaseAdapter extends XmlAdapter<BaseAdapter.BaseHandler,Base>{
@Override
public Base unmarshal(BaseHandler baseHandler) throws Exception {
if (null == baseHandler) {
return null;
}
if (null != baseHandler.dataA1) {
A a = new A();
a.setDataA1(baseHandler.dataA1);
a.setDataA2(baseHandler.dataA2);
return a;
} else {
B b = new B();
b.setDataB1(baseHandler.dataB1);
b.setDataB2(baseHandler.dataB2);
return b;
}
}
@Override
public BaseHandler marshal(Base base) throws Exception {
if (null == base) {
return null;
}
BaseHandler baseHandler = new BaseHandler();
if (base instanceof A) {
A a = (A) base;
baseHandler.dataA1 = a.getDataA1();
baseHandler.dataA2 = a.getDataA2();
} else {
B b = (B) base;
baseHandler.dataB1 = b.getDataB1();
baseHandler.dataB2 = b.getDataB2();
}
return baseHandler;
}
public static class BaseHandler {
public String dataA1;
public String dataA2;
public String dataB1;
public String dataB2;
}
}
如果有人感兴趣, 这里是完整的SSCCE代码 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.