Кажется, у меня проблемы с 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 или как решить проблему вызова веб-службы и более простого отображения этих объектов. Я искал несколько дней, и мне грустно кажется, что я в тупике.