带有自定义JAX-B绑定的JAX-WS MarshalException:无法封送类型“java.lang.String”作为一个元素 [英] JAX-WS MarshalException with custom JAX-B bindings: Unable to marshal type "java.lang.String" as an element

查看:67
本文介绍了带有自定义JAX-B绑定的JAX-WS MarshalException:无法封送类型“java.lang.String”作为一个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎遇到了Jax-WS和Jax-b一起玩的问题。我需要使用一个具有预定义WSDL的Web服务。执行生成的客户端时,我收到以下错误:

I seem to be having an issue with Jax-WS and Jax-b playing nicely together. I need to consume a web-service, which has a predefined WSDL. When executing the generated client I am receiving the following error:


javax.xml.ws.WebServiceException:javax.xml.bind.MarshalException - 链接异常:
[com.sun.istack.SAXException2:无法封装类型java.lang.String作为元素,因为它缺少@XmlRootElement注释]

javax.xml.ws.WebServiceException: javax.xml.bind.MarshalException - with linked exception: [com.sun.istack.SAXException2: unable to marshal type "java.lang.String" as an element because it is missing an @XmlRootElement annotation]

当我使用外部自定义绑定文件将不必要的复杂类型映射到java.lang.string时,就会发生这种情况。以下是我的绑定文件的摘录:

This started occurring when I used an external custom binding file to map needlessly complex types to java.lang.string. Here is an excerpt from my binding file:

<?xml version="1.0" encoding="UTF-8"?>
  <bindings xmlns="http://java.sun.com/xml/ns/jaxb" version="2.0" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
      xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc">
    <bindings schemaLocation="http://localhost:7777/GESOR/services/RegistryUpdatePort?wsdl#types?schema1" node="/xs:schema">
      <bindings node="//xs:element[@name='StwrdCompany']//xs:complexType//xs:sequence//xs:element[@name='company_name']">
        <property>
          <baseType name="java.lang.String" />
        </property>
      </bindings>
      <bindings node="//xs:element[@name='StwrdCompany']//xs:complexType//xs:sequence//xs:element[@name='address1']">
        <property>
          <baseType name="java.lang.String" />
        </property>
      </bindings>
      <bindings node="//xs:element[@name='StwrdCompany']//xs:complexType//xs:sequence//xs:element[@name='address2']">
        <property>
          <baseType name="java.lang.String" />
        </property>
      </bindings>
      ...more fields
  </bindings>
</bindings>

当对提供的WSDL执行wsimport时,会生成StwrdCompany并声明以下变量:

When executing wsimport against the provided WSDL, StwrdCompany is generated with the following variables declared:

@XmlRootElement(name = "StwrdCompany")
public class StwrdCompany 
{
    @XmlElementRef(name = "company_name", type = JAXBElement.class)
    protected String companyName;
    @XmlElementRef(name = "address1", type = JAXBElement.class)
    protected String address1;
    @XmlElementRef(name = "address2", type = JAXBElement.class)
    ... more fields

    ... getters/setters

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "value"
    })
    public static class CompanyName {

        @XmlValue
        protected String value;
        @XmlAttribute
        protected Boolean updateToNULL;

        /**
         * Gets the value of the value property.
         * 
         * @return
         *     possible object is
         *     {@link String }
         *     
         */
        public String getValue() {
            return value;
        }

        /**
         * Sets the value of the value property.
         * 
         * @param value
         *     allowed object is
         *     {@link String }
         *     
         */
        public void setValue(String value) {
            this.value = value;
        }

        /**
         * Gets the value of the updateToNULL property.
         * 
         * @return
         *     possible object is
         *     {@link Boolean }
         *     
         */
        public boolean isUpdateToNULL() {
            if (updateToNULL == null) {
                return false;
            } else {
                return updateToNULL;
            }
        }

        /**
         * Sets the value of the updateToNULL property.
         * 
         * @param value
         *     allowed object is
         *     {@link Boolean }
         *     
         */
        public void setUpdateToNULL(Boolean value) {
            this.updateToNULL = value;
        }

       ... more inner classes
       }
   }

最后,这里是来自WSDL的关联片段,似乎引起了这样的悲痛。

Finally, here is the associated snippet from the WSDL that seems to be causing such grief.

<xs:element name="StwrdCompany">
  <xs:complexType>
    <xs:sequence>
      <xs:element maxOccurs="1" minOccurs="0" name="company_name" nillable="true">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="xs:string">
              <xs:attribute default="false" name="updateToNULL" type="xs:boolean"/>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
      <xs:element maxOccurs="1" minOccurs="0" name="address1" nillable="true">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="xs:string">
              <xs:attribute default="false" name="updateToNULL" type="xs:boolean"/>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
      ... more fields in the same format

      <xs:element maxOccurs="1" minOccurs="0" name="p_source_timestamp" nillable="false" type="xs:string"/>
    </xs:sequence>
    <xs:attribute name="company_xid" type="xs:string"/>
  </xs:complexType>
</xs:element>

自定义绑定的原因是我可以将用户输入从pojo映射到StwrdCompany对象更多很容易,无论是直接实例化还是通过使用Dozer进行bean映射。没有自定义绑定,我无法在对象之间成功映射。

The reason for the custom binding is so I can map user input from a pojo into the StwrdCompany object more easily, whether it be direct instantiation or through the use of Dozer for bean mapping. I was unable to successfully map between the objects without the custom binding.

最后,我尝试的另一件事是设置globalBinding定义:

Finally, one other thing I tried was setting a globalBinding definition:

<globalBindings generateValueClass="false"></globalBindings>  

这导致服务器通过参数不匹配异常,因为Soap Message使用xs:string xml类型而不是传递定义的复杂类型,所以我放弃了这个想法。

This caused the server to through an argument mismatch exception since the Soap Message was using xs:string xml types instead of passing the defined complex types, so I abandoned that idea.

任何洞察导致MarshalException的原因或如何解决调用webservice和非常感谢更容易地映射这些对象。我一直在寻找几天,我很遗憾地认为我很难过。

Any insight into what is causing the MarshalException or how to go about solving the issue of calling the webservice and mapping these objects more easily, is greatly appreciated. I've been searching for days and I sadly think I am stumped.

推荐答案

您需要添加< xjc:simple /> < jaxb:globalBindings> 部分中的元素,用于使JAXB正确处理根元素。只需将以下内容插入绑定文件

You need to add a <xjc:simple /> element inside your <jaxb:globalBindings> section for making JAXB handling root elements correctly. Just insert the following into your bindings file

<jaxb:globalBindings>
   <xjc:simple />
</jaxb:globalBindings>

我有一个JAXB映射样本这里你可以用来获取灵感。

I have a JAXB mapping sample here you can use for inspiration.

这篇关于带有自定义JAX-B绑定的JAX-WS MarshalException:无法封送类型“java.lang.String”作为一个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆