天天看点

unmarshaller.unmarshal转换结果是JAXBElement问题问题描述问题解决

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注解,加上注解后,问题解决。