我似乎遇到了Jax-WS和Jax-b一起玩的问题。我需要使用一个具有预定义WSDL的Web服务。执行生成的客户端时,我收到以下错误:
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>
对提供的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>
自定义绑定的原因是我可以更轻松地将用户输入从pojo映射到StwrdCompany对象,无论是直接实例化还是通过使用Dozer进行bean映射。没有自定义绑定,我无法在对象之间成功映射。
最后,我尝试的另一件事是设置一个globalBinding定义:
<globalBindings generateValueClass="false"></globalBindings>
这导致服务器通过参数不匹配异常,因为Soap Message使用xs:string xml类型而不是传递定义的复杂类型,所以我放弃了这个想法。
非常感谢任何有关导致MarshalException的原因或如何解决调用web服务和更轻松地映射这些对象的问题。我一直在寻找几天,我很遗憾地认为我很难过。
答案 0 :(得分:2)
您需要在<xjc:simple />
部分中添加<jaxb:globalBindings>
元素,以使JAXB正确处理根元素。只需将以下内容插入绑定文件
<jaxb:globalBindings>
<xjc:simple />
</jaxb:globalBindings>
我有一个JAXB映射样本here,您可以使用它来获取灵感。
答案 1 :(得分:1)
该错误意味着JAXB正在尝试对String进行编组,就好像它是一个XML元素 - 显然它不是。因此,例如将“foo”编组为XML,实际上应该是“foo”之类的东西。这样做的原因是因为映射...使一个元素到一个String也具有相同的效果:所以它试图将String映射到一个元素,这会导致无效的XML。
Lars的解决方案应该有效。您可以做的另一件事是将它映射到JAXB可以编组的(简单)自定义类。如果你很勇敢,你也可以尝试使用JAXBElement。