I seem to have a problem with Jax-WS and Jax-b, which play beautifully together. I need to use a web service with a predefined WSDL. When executing the generated client, I get the following error:
javax.xml.
It started when I used an external binding file to map unnecessary 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>
When wsimport is executed against the provided WSDL, the StwrdCompany is generated with the following declared variables:
@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; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public boolean isUpdateToNULL() { if (updateToNULL == null) { return false; } else { return updateToNULL; } } public void setUpdateToNULL(Boolean value) { this.updateToNULL = value; } ... more inner classes } }
Finally, here is a related snippet from WSDL that seems to cause 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>
The reason for user binding is that I can more easily map user input to pojo in a StwrdCompany object, whether it be a direct instance or using a Dozer mapping for a bean. I was unable to successfully match objects without user binding.
Finally, another thing I tried was defining a globalBinding definition:
<globalBindings generateValueClass="false"></globalBindings>
This led to the server going through an argument mismatch exception because the soap message used xs: string xml types instead of passing certain complex types, so I gave up on this idea.
Any understanding of what causes a MarshalException or how to solve the problem of calling a web service and matching these objects is greatly appreciated. I have been looking for days, and I sadly think I'm at a standstill.
java soap web-services jax-ws jaxb
tnicks
source share