java - 带有自定义 JAX-B 绑定(bind)的 JAX-WS MarshalException : Unable to marshal type "java.lang.String" as an element

标签 java web-services soap jaxb jax-ws

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

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]

当我使用外部自定义绑定(bind)文件将不必要的复杂类型映射到 java.lang.string 时,就开始出现这种情况。这是我的绑定(bind)文件的摘录:

<?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,并声明以下变量:

@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 的相关片段,它似乎导致了这种悲痛。

<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>

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

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

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

由于 Soap 消息使用 xs:string xml 类型而不是传递已定义的复杂类型,这导致服务器出现参数不匹配异常,因此我放弃了这个想法。

如能深入了解导致 MarshalException 的原因或如何更轻松地解决调用 web 服务和映射这些对象的问题,我们将不胜感激。我已经找了好几天了,可悲的是我觉得自己被难住了。

最佳答案

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

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

我有一个 JAXB 映射示例 here你可以用来寻找灵感。

关于java - 带有自定义 JAX-B 绑定(bind)的 JAX-WS MarshalException : Unable to marshal type "java.lang.String" as an element,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2626771/

相关文章:

java - Elasticsearch 将多个字段与 AND 运算符匹配不起作用

java - 为什么外部Java类可以访问内部类私有(private)成员?

java - Web 服务器生成格式错误的 services.wsdl

Java 编译器看不到我的类

java - 如何用 java 将文件上传到 Restful Web 服务?

java - 为什么 CloudWatchConfig 接口(interface)需要一个步骤持续时间的字符串

java - Java 邮件中的 TransportEvent 何时被触发?

javascript - 将图像从移动网络应用程序(PhoneGap 和 JavaScript)上传到 SOAP 网络服务返回状态 0

java - 代理服务器上的 JAX-WS 客户端身份验证

java - 应用程序在设备/模拟器中运行时崩溃