无法使用JAXB编组映射,因为:无法将类型“java.lang.String”编组为元素,因为它缺少@XmlRootElement注释

时间:2014-03-17 09:19:48

标签: java jaxb jax-ws

在创建JAX-WS Web服务时,我遇到了使用JAXB(Java版本1.6.0_26)将java.util.Map编组为XML的问题。 有问题的地图是原始类型,无法更改。地图键可能是运行时的字符串,但值可以是其他对象,包括其他地图和列表

似乎大多数方法(如this onethis one)用于使用JAXB封送原始类型映射,通常建议使用XmlAdapter将映射转换为更适合JAXB的结构,以便之后它可以很容易地编组。我试图遵循这种方法,但我无法摆脱这个错误:

com.sun.istack.SAXException2: unable to marshal type "java.lang.String" as an element because it is missing an @XmlRootElement annotation

更多信息

在推荐的方法中,XmlAdapter的模式总是如下:

  1. 您必须创建一个JAXB友好类,它将是一个容器 - 名为MyMapAdapterMap或类似 - 并且它应该有List作为字段。
  2. MyMap的list属性如下所示:

    List<Entry<K, V>> list = new ArrayList<Entry<K, V>>();

  3. Entry类封装了密钥K和值V对,看起来基本上是这样的:

    @XmlRootElement
    public class Entry<K, V> {
    
        @XmlElement
        private K key;
    
        @XmlElement
        private V value;
    
        ...
    }
    
  4. 您撰写的XmlAdapter会在java.util.Map方法中将MyMap转换为marshal,并在unmarshal方法中执行相反的操作。< / p>

  5. 我无法准确确定问题所在,但我相信JAXB在类型K key(可能还有其他类型)时无法封送java.lang.String属性。如果类型明确声明为String而不是K,那么我确定它会起作用,但这不是我可以假设的,无论如何我不能对V做同样的事情。 ,这可能是绝对的。

    顺便说一下,因为我知道我需要编组和解组的地图将包含其他(嵌套)地图,我使用“RecursiveMapAdapter”找到了看起来像neat solution的地图但是这又导致了同样的问题

    Caused By: com.sun.istack.SAXException2: unable to marshal type "java.lang.String" as an element because it is missing an @XmlRootElement annotation
            at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:248)
            at com.sun.xml.bind.v2.runtime.LeafBeanInfoImpl.serializeRoot(LeafBeanInfoImpl.java:137)
            at com.sun.xml.bind.v2.runtime.property.ArrayReferenceNodeProperty.serializeListBody(ArrayReferenceNodeProperty.java:114)
            at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:152)
            at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:332)
            at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:699)
            at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:152)
            at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:332)
            at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:699)
            at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:65)
            at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:168)
            at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:152)
            at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:332)
            at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:699)
            at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:152)
            at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:332)
            at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:593)
            at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:320)
            at com.sun.xml.bind.v2.runtime.property.ArrayReferenceNodeProperty.serializeListBody(ArrayReferenceNodeProperty.java:114)
            at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:152)
            at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:332)
            at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:328)
            at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:699)
            at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:152)
            at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:332)
            at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:699)
            at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:152)
            at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:127)
            at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeBody(ElementBeanInfoImpl.java:316)
            at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:323)
            at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:72)
            at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:494)
            at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:315)
            at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:244)
            at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:75)
            at org.apache.cxf.jaxb.JAXBEncoderDecoder.writeObject(JAXBEncoderDecoder.java:539)
            at org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:233)
            at org.apache.cxf.jaxb.io.DataWriterImpl.write(DataWriterImpl.java:168)
            at org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor.writeParts(AbstractOutDatabindingInterceptor.java:112)
            at org.apache.cxf.interceptor.BareOutInterceptor.handleMessage(BareOutInterceptor.java:68)
            at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
            at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:530)
            at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:463)
            at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:366)
            at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319)
            at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
            at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
            at $Proxy202.doTheWebServiceCall(Unknown Source)
    

0 个答案:

没有答案