I've been wanting to ask this question of the list for some time, but I've put 
it  trying to see how far I could get.

Firstly, I am using a code first method and generating the WSDL.  CXF 2.3.1, 
JBoss6.  No options to upgrade further.

I have written an application level framework that makes it very easy for me to 
implement new web services and operations, which usually are just exposing some 
information from a database.  This framework takes care of auditing records of 
web service requests, supports requests of  asynchronous data extracts,  
polling  the status of the extract, and returning results, optionally in 
"chunks".

In addition to the results, I wanted all of my web service responses to include 
some metadata about that request/response.   So, I created a "PayLoad" object 
which would contain a ResponseInfo object with the metadata and a 
List<PayLoadOjbect>.   So, all of my operations, across all web services return 
a PayLoad with its PayLoadList containing the results of their request.

Now, if you have an opinion on the general design of return results in an 
enclosing object with metadata like this,  whether or not there are other, 
better patterns of doing this or difficulties of consuming such services as a 
client, I'd be interested to hear them.   Otherwise...

...my problem is the list of results.  For some time I have had it returning

<PayLoad>
                <responseInfo> ...</responseInfo>
            <payLoadList>
               <payLoadObject xsi:type="ns2:MyBean" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
                ...
</payLoadObject>
...
           </payLoadList>
</PayLoad>

My problem with this is that, even though all of the complex types returned are 
defined in the WSDL (because I have @XmlSeeAlso annotations in the service), 
there was no way for a consumer of the WSDL to determine exactly what type is 
returned by a specific operation.   Clients accessing the PayLoad list would 
need to "know" what type to expect in the payLoadList and cast them to the 
proper type.   (Clients have to have certs on file, so this seemed like a 
documentation problem to me.)  Also, I didn't like having the abstract super 
class, because if I needed to write a web service operation "aligned" with some 
external third party webservice, i.e.,  returned objects from other namespaces, 
I would have to modify them to extend that class to work with my framework.

So, next I got rid of PayLoadObject abstract class and just had my PayLoadList 
returning a list of Object.  The response XML looks exactly the same.   (I had 
not read about XML substitution groups, which sound promising and seem to 
require an abstract super class , but the aforementioned negatives still would 
be a consideration.  Is this the only way I can accomplish what I want and have 
it validate??)

Still, what I wanted was for the PayLoadList to look like *this*, with nodes of 
the proper element  name appearing in the payLoadList, not objects with a type 
attribute.  I am still quite a novice at writing web service clients, but in my 
first attempt, I had to cast the objects in the payLoadList to appropriate 
objects.  JAXB didn't unmarshal objects of the actual result type.

            <payLoadList>
               < ns2:MyBean>...</ns2:MyBean>
                ...
</payLoadObject>

The next thing I tried was parameterizing my PayLoad class, so that I would 
have my framework work with PayLoad<T>, my web service operations return 
PayLoad<ResultObjectClass>.    But the result was still the same, and not what 
I wanted.

So, along the lines of this blog tutorial, 
http://blog.bdoughan.com/2012/11/creating-generic-list-wrapper-in-jaxb.html, I 
created a ListWrapper<T> object, modified the List<T> in my PayLoad<T> to be a 
ListWrapper<T>.

In the ListWrapper<T>,  the get method for the enclosed list is annotated with 
@XmlAnyElement(lax=true)

Now, the XML being returned is exactly the way I want it!  But, my NEW problem 
is that my WSDL still doesn't seem to adequately describe what is being 
returned.    So, now my SoapUi test cases are all failing schema compliance 
assertions with an error along the lines of "Element not allowed: MyBean in 
element payLoadList".

So, in my WSDL:

<xs:complexType name="payLoad">
<xs:sequence>
<xs:element minOccurs="0" name="responseInfo" type="tns:wsResponseInfo" />
<xs:element minOccurs="0" name="payLoadList" type="tns:listWrapper" />
</xs:sequence>
</xs:complexType>
...
<xs:complexType name="listWrapper">
<xs:sequence>
<xs:any maxOccurs="unbounded" minOccurs="0" namespace="##other" 
processContents="lax" />
</xs:sequence>
</xs:complexType>


I don't know how to set namespace="##targetNamespace".  Would that solve my 
problem?  Is the substitution group approach
(like this: 
http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html) 
the only way (I'd have to resurrect my PayLoadObject)?  I'm not sure I 
understand this completely yet, but I'd like to avoid any dependencies of my 
framework classes, like PayLoad, on result classes defined in web service 
client modules.

Any suggestions or thoughts?



n  Andrew

Reply via email to