简短的回答:在您的界面字段上使用。@XmlElement(type = Object.class)
详情如下:
我已经找到了2种方法,你可以让JAXB序列化你的接口:
@XmlAnyElement
@XmlElement(type = Object.class)
1.@XmlAnyElement
只需使用@XmlAnyElement
注释接口类型字段,JAXB 就会从接口的具体类型序列化接口。不要忘记使用@XmlRootElement
注释具体类型,并将具体类型添加到 JAXBContext 中。完整示例如下:
public class InterfaceSerializer {
@XmlRootElement
public static class Pojo {
Pojo() {
field1 = new PojoFieldImpl1();
field2 = new PojoFieldImpl2();
field3 = new PojoFieldImpl1();
}
@XmlAnyElement
public IPojoField field1;
@XmlAnyElement
public IPojoField field2;
@XmlAnyElement
public IPojoField field3;
@Override
public String toString() {
return "field1 = " + field1 + "\nfield2 = " + field2 + "\nfield3 = " + field3;
}
}
public static interface IPojoField {
}
@XmlRootElement
public static class PojoFieldImpl1 implements IPojoField {
PojoFieldImpl1() {
value = "PojoFieldImpl1 value";
}
public String value;
@Override
public String toString() {
return value;
}
}
@XmlRootElement
public static class PojoFieldImpl2 implements IPojoField {
PojoFieldImpl2() {
value = "PojoFieldImpl2 value1";
value2 = "PojoFieldImpl2 value2";
}
public String value;
public String value2;
@Override
public String toString() {
return value + " " + value2;
}
}
public static void main(String []args) throws JAXBException {
Pojo pojo = new Pojo();
JAXBContext jaxbContext = JAXBContext.newInstance(Pojo.class, PojoFieldImpl1.class, PojoFieldImpl2.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(pojo, new File("interfaceSerializer.xml"));
}
}
输出 XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<pojo>
<pojoFieldImpl1>
<value>PojoFieldImpl1 value</value>
</pojoFieldImpl1>
<pojoFieldImpl2>
<value>PojoFieldImpl2 value1</value>
<value2>PojoFieldImpl2 value2</value2>
</pojoFieldImpl2>
<pojoFieldImpl1>
<value>PojoFieldImpl1 value</value>
</pojoFieldImpl1>
</pojo>
此方法的缺点:
- 您无法将每个字段与pojo与XML区分开来(相同的实现将使用相同的标记编写)
- 您没有任何类型信息来取消您的XML(如果您愿意,可以这样做)
这些缺点在第二种解决方案中是固定的:
2.@XmlElement(类型 = 对象.class)
我在mikesir87的博客文章中偶然发现了这一点。只需将上面的@XmlAnyElement
注释替换为@XmlElement(type = Object.class)
在上面的Pojo类中应该有这样的东西:
@XmlElement(type = Object.class)
public IPojoField field1;
@XmlElement(type = Object.class)
public IPojoField field2;
@XmlElement(type = Object.class)
public IPojoField field3;
重新运行我们的示例,即生成的 XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<pojo>
<field1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="pojoFieldImpl1">
<value>PojoFieldImpl1 value</value>
</field1>
<field2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="pojoFieldImpl2">
<value>PojoFieldImpl2 value1</value>
<value2>PojoFieldImpl2 value2</value2>
</field2>
<field3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="pojoFieldImpl1">
<value>PojoFieldImpl1 value</value>
</field3>
</pojo>
这也可以反序列化:
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Pojo unmarshalledPojo = (Pojo) unmarshaller.unmarshal(new File("interfaceSerializer.xml"));
System.out.println(unmarshalledPojo);
结果输出:
field1 = PojoFieldImpl1 value
field2 = PojoFieldImpl2 value1 PojoFieldImpl2 value2
field3 = PojoFieldImpl1 value
可能是一个“黑客”解决方案,但它可以完成工作。