unmarshaller.unmarshal转换结果是JAXBElement问题
- 问题描述
- 问题解决
-
-
-
-
- 解释一下:
- 回去一看
-
-
-
问题描述
根据xml字符串转换成对象,返回的类型不是传入的Class类对象,而是JAXBElement对象。
示例:
public <T> T fromXml(String xml, Class<T> targetClass, String encoding) {
try {
JAXBContext jaxbContext = createContext(targetClass);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
XMLStreamReader read = XMLInputFactory.newInstance().createXMLStreamReader(
new ByteArrayInputStream(xml.getBytes(encoding)));
T object = (T) unmarshaller.unmarshal(read);
return object; //此时返回的不是targetClass实例,而是JAXBElement对象,JAXBElement对象中的value属性确是targetClass实例
} catch (Exception e) {
...
}
}
问题解决
https://stackoverflow.com/questions/10243679/when-does-jaxb-unmarshaller-unmarshal-returns-a-jaxbelementmyschemaobject-or-a
-
It depends on the presence of XmlRootElement annotation on the class of your root element.
If you generate your JAXB classes from an XSD, the following rules are applied:
if the type of the root element is an anonymous type -> XmlRootElement annotation is added to the generated class
if the type of the root element is a top level type -> XmlRootElement annotation is omitted from the generated class
For that reason I often choose anonymous types for root elements.
You can customize the class name of this anonymous type with a customization file. E.g. create a bindings.xjc file like this:
<jxb:bindings version=“1.0”
xmlns:jxb=“http://java.sun.com/xml/ns/jaxb”
xmlns:xs=“http://www.w3.org/2001/XMLSchema”>
<jxb:bindings schemaLocation=“yourXsd.xsd” node="/xs:schema">
<jxb:bindings node="//xs:element[@name=‘yourRootElement’]">
<jxb:class name=“YourRootElementType”/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
解释一下:
和XmlRootElement 注解有关,如果你的xml的bean类是从xsd生成的,那么就会出现这些情况:
- 如果根元素的类型是匿名类型-> XmlRootElement注解将自动添加到生成的类中
- 如果根元素的类型是顶级类型->生成的类中会省略XmlRootElement注解
回去一看
当前转化的类的确没有XmlRootElement注解,加上注解后,问题解决。