JAX-WS MarshalException с пользовательскими привязками JAX-B: невозможно маршалировать тип «java.lang.String» в качестве элемента - PullRequest
4 голосов
/ 13 апреля 2010

Кажется, у меня проблемы с Jax-WS и Jax-b, которые хорошо играют вместе. Мне нужно использовать веб-сервис, который имеет предопределенный WSDL. При выполнении сгенерированного клиента я получаю следующую ошибку:

javax.xml.ws.WebServiceException: javax.xml.bind.MarshalException - со связанным исключением: [com.sun.istack.SAXException2: невозможно маршалировать тип «java.lang.String» в качестве элемента, поскольку отсутствует аннотация @XmlRootElement]

Это начало происходить, когда я использовал внешний пользовательский файл привязки для сопоставления ненужных сложных типов с java.lang.string. Вот выдержка из моего обязательного файла:

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

При выполнении wsimport для предоставленного WSDL генерируется 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>

Причина пользовательской привязки заключается в том, что я могу более легко отобразить пользовательский ввод из pojo в объект StwrdCompany, будь то прямое создание экземпляров или использование Dozer для отображения bean-компонентов. Мне не удалось успешно отобразить объекты без пользовательской привязки.

Наконец, еще одна вещь, которую я попробовал, - установить определение globalBinding:

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

Это привело к тому, что на сервере произошла исключительная ситуация несоответствия аргументов, поскольку в сообщении Soap использовались типы xs: string xml вместо передачи определенных сложных типов, поэтому я отказался от этой идеи.

Будем весьма благодарны за понимание того, что вызывает исключение MarshalException или как решить проблему вызова веб-службы и более простого отображения этих объектов. Я искал несколько дней, и мне грустно кажется, что я в тупике.

Ответы [ 2 ]

2 голосов
/ 20 апреля 2010

Вам необходимо добавить элемент <xjc:simple /> внутри раздела <jaxb:globalBindings>, чтобы JAXB правильно обрабатывал корневые элементы. Просто вставьте следующее в файл привязок

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

У меня есть образец картографии JAXB здесь , который вы можете использовать для вдохновения.

1 голос
/ 26 апреля 2010

Эта ошибка означает, что JAXB пытается маршалировать String, как если бы это был элемент XML - что, очевидно, не так. Так, например, маршалинг «foo» как XML, когда на самом деле это должно быть что-то вроде «foo». Это происходит из-за сопоставления ... создание элемента в String также имеет тот же эффект, что и в другом случае: он пытается сопоставить String с элементом, что приводит к неверному XML.

Раствор Ларса с должен работать. Другая вещь, которую вы можете сделать, это сопоставить ее с (простым) пользовательским классом, который JAXB может собрать. Если вы смелы, вы можете попробовать поиграться с JAXBElement.

...