Returning a String in a variable content container list fails schema validation due to namespace declaration attributes

Tag: java , web-services , jaxb , jax-ws Author: vensylove Date: 2014-04-22

I have a code first web service annotated with JAX-WS annotations. My operation returns a PayLoad object, which is defined and annotated like this:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlRootElement(namespace="http://mycompany.com")
@XmlType(propOrder = { "responseInfo", "payLoadList" })
public class PayLoad<T> implements Serializable {

    private WSResponseInfo responseInfo;

    @XmlElementWrapper(name = "payLoadList")
    @XmlElement(name = "payLoadObject")       
    private List<T> payLoadList = new ArrayList<T>();
    [...]
}

In the WSDL that is generated, PayLoad appears as a complex type with payLoadList as an anonymous complex type:

     <xs:complexType name="payLoad">
        <xs:sequence>
           <xs:element minOccurs="0" name="responseInfo" type="tns:wsResponseInfo"/>
           <xs:element minOccurs="0" name="payLoadList">
              <xs:complexType>
                 <xs:sequence>
                    <xs:element maxOccurs="unbounded" minOccurs="0" name="payLoadObject" nillable="true" type="xs:anyType"/>
                 </xs:sequence>
              </xs:complexType>
           </xs:element>
        </xs:sequence>
     </xs:complexType>

Most of my web service operations return complex types with no issues. I wrestled with different approaches to this variable content container. I had my payLoadList returning an abstract PayLoadObject which all my other result objects extended. I wanted to try to return elements of the correct type, without an xsi:type attribute, so I tried two different approaches from Blaise Doughan's excellent blog:

Creating a Generic List Wrapper in JAXB and JAXB and Inheritance - Using Substitution Groups

...although with the latter, I used an abstract PayLoadObject and an @XmlElementRef annotation and ended up with xs:choice entries for the PayLoadList (ref: JAXB Converts XmlElementRef and XmlElements to xs:choice

This worked and I got elements of the appropriate complex element type in the payLoadList, but I still didn't like the necessity of having an abstract super class. Additionally, I have one operation that appears in all of my web services to ping the web service and return a String, which then had problems because it is not annotated with XmlElementRef.

I was concerned about complicating things for consumers of my web service and confused about which was the best way to do this. Then, I read this paper Creating Variable Content Container Elements and decided that maybe my initial approach of using xsi:type was best. However, I still don't want the abstract superclass PayLoadObject, so I found I was able to get the same results by returning just PayLoad[T] instead of PayLoad[T extends PayLoadObject].

But, I still have one problem, with the test method that just returns a String. The response I get back looks like this:

<ns2:payLoad>
<responseInfo>
[...]
</responseInfo>
<payLoadList>
<payLoadObject xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Test2 of the WS-VTA Web Service</payLoadObject>
</payLoadList>
</ns2:payLoad>

This seems to pass validation on the server side (enabling JAX-WS schema validation), but fails on the client side in SoapUi where I get a validation error from this with the error: Invalid xsi:type qname: 'xs:string' in element payLoadList. I see something similar to this logged as a bug with SoapUi from way back in 2009, but it was supposedly resolved.

Now, if I remove the xmlns declaration attributes from the payLoadObject (just editing the response in SoapUi), then it validates properly.

So, my questions are: why do these namespace declarations appear on this payLoadList element? They are the same namespaces and prefixes that appear in my WSDL.

xs:String is a valid type for xsi:type, yes? I have seen plenty of other examples where people do this and I don't understand what I might be doing differently.

And, lastly, if anyone has more general feedback on "best practices" for variable content containers, particularly with regards to making it as friendly as possible for web service clients, I would be interested in that as well.

The reason why I am using such a container is that I have written an application level framework to handle tying in web service requests and responses to an audit table, handling of responses in a synchronous or asynchronous manner, status reporting etc. I just create a DAO object to fetch what I need, create a concrete implementation of an AbstractService and expose a method for the operation. So, I needed/wanted a standardized PayLoad response data structure that could contain both metadata about a request and the actual results, if any.

Thank you in advance for your time and trouble...

Edit: Actually, I suspect the only reason it does not fail schema validation on the server side is because contents of the body tag (including the PayLoad) are encrypted.