以下java属性可以是String / Integer类型。我尝试添加注释,如下所示,但它只采用最后一种类型(在这种情况下为字符串),即使传递整数。我们如何为这个属性允许多种类型?
@XmlElements({
@XmlElement(type = Integer.class), @XmlElement(type = String.class)
})
private Object val1;
答案 0 :(得分:2)
问题是在解组时没有名称来区分不同类型的类。我不知道你的要求到底是什么,但这就是你如何使它发挥作用:
@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
public class SomeRoot {
@XmlElements({
@XmlElement(name="string", type = String .class),
@XmlElement(name="int", type = Integer.class)
})
private Object val;
public SomeRoot(Object val) {
this.val = val;
}
public SomeRoot() { }
}
当你提供了一个字符串值时,它将被编组成类似的东西:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<string>test</string>
</root>
当给出一个整数时,它会编组成类似的东西:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<int>1</int>
</root>
由于元素名称的不同,这两种方法都会被解组为正确的类型。
此外,如果你有一个对象列表,你可以编组/解组这样的东西没有问题:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<int>1</int>
<string>test1</string>
<string>test2</string>
<string>test3</string>
<int>3</int>
</root>
更新
如果您想在<val>
元素下使用这两种类型,则可以使用自定义XmlAdapter来检查类型。这看起来像这样:
public class MyXmlAdapter extends XmlAdapter<Object, Object> {
private DocumentBuilder documentBuilder;
public MyXmlAdapter() {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
documentBuilder = dbf.newDocumentBuilder();
} catch(Exception e) {
// TODO - Handle Exception
}
}
@Override
public Object unmarshal(Object v) throws Exception {
Element element = (Element) v;
String elementValue = element.getTextContent();
if(StringUtils.isNumeric(elementValue)) {
return Integer.parseInt(elementValue);
} else {
return new String(elementValue);
}
}
@Override
public Object marshal(Object v) throws Exception {
return v;
}
}
你的根类就是这样的:
@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
public class SomeRoot {
@XmlJavaTypeAdapter(MyXmlAdapter.class)
private Object val;
public SomeRoot(Object val) {
this.val = val;
}
public SomeRoot() { }
public Object getVal() {
return val;
}
}
在一个简单的main中尝试这个,在val上将提供的xml解析为String和Integer的正确类型:
public static void main(String[] args) {
try {
File file = new File("file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(SomeRoot.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
jaxbUnmarshaller.setAdapter(new MyXmlAdapter());
SomeRoot pojo = (SomeRoot) jaxbUnmarshaller.unmarshal(file);
System.out.println(pojo.getVal().getClass());
} catch (JAXBException e) {
e.printStackTrace();
}
}