JAX-WS MarshalException with custom bindings JAX-B: Cannot marshal type "java.lang.String" as an element

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; /** * 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 } } 

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.

+4
java soap web-services jax-ws jaxb
source share
2 answers

You need to add the <xjc:simple /> element to your <jaxb:globalBindings> section to properly handle the JAXB root elements. Just paste the following into your bindings file

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

I have a JAXB mapping pattern here that you can use for inspiration.

+2
source share

This error means that JAXB is trying to arrange the string as if it were an XML element, which obviously is not. So, for example, marshalling "foo" as XML, when really it should be something like "foo". The reason this happens is because of the mapping ... creating an element in String also has the same effect in a different way: therefore, it tries to map String to the element, which results in invalid XML.

Lars decision should work. Another thing you can do is map it to a (simple) custom class that JAXB can marshal. If you are brave, you can try communicating with JAXBElement too.

+1
source share

All Articles