When dealing with polymorphism with JAXB, one thing that is often required is 
to add XmlSeeAlso annotations all over the place.  In particular, on the base 
class, it's  useful to have XmlSeeAlso point at the potential subclasses.   
This allows the jaxb runtime to find the subclasses to instantiate and will 
usually result in the proper xsi:type attributes written out and such.   

If you haven't already tried it, I'd definitely suggest adding the annotation 
and seeing if that helps.

Dan


On Friday 15 April 2011 4:02:17 PM Simon Chen wrote:
> Hi all,
> 
> I've been playing with building a REST web service to handle
> polymorphism... It's a long post, but bear with me :-)
> 
> In particular, I may have:
> 
> @Path("/")
> class WebStore {
>   @POST
>   @Path("/customers/")
>   Response addCustomer(Customer c) {
>     ...
>   }
> }
> 
> But I have a base class of Customer, but also inherited classes of
> AwesomeCustomer, and SuperAwesomeCustomer. Things get more complicated
> when EMF kicks in, where I actually have a Customer interface and
> CustomerImpl class.
> 
> The previous declaration doesn't work when I post a customer XML snippet,
> say: <customer><name>simon</name></customer>
> 
> Because Customer is an interface, so cannot be annotated with
> @XmlRootElement. As a result, the error of "no message body reader can
> be found" is raised...
> 
> If we change the POST function this way, it can work:
>   @POST
>   @Path("/customers/")
>   Response addCustomer(CustomerImpl c) {
>     ...
>   }
> 
> But, this breaks again, when I add the following:
>   @POST
>   @Path("/customers/")
>   Response addCustomer(CustomerImpl c) {
>     ...
>   }
>   @POST
>   @Path("/customers/")
>   Response addCustomer(AwesomeCustomerImpl c) {
>     ...
>   }
>   @POST
>   @Path("/customers/")
>   Response addCustomer(SuperAwesomeCustomerImpl c) {
>     ...
>   }
> 
> Here, if I post a SuperAwesomeCustomerImpl object to "/customers", the
> ws would find all the functions that can handle "POST to /customers",
> which will include all three functions above. However, in
> "src/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.
> java", public static OperationResourceInfo findTargetMethod(), we have:
> 
>         if (!candidateList.isEmpty()) {
>             Map.Entry<OperationResourceInfo, MultivaluedMap<String,
> String>> firstEntry =
>                 candidateList.entrySet().iterator().next();
>             //---------> This only looks at the first function that
> matches, while not look at the class hierarchy...
>             values.clear();
>             values.putAll(firstEntry.getValue());
>             OperationResourceInfo ori = firstEntry.getKey();
> 
> 
> Hopefully, I am not overwhelming everyone with too much information.
> But is there a fix to this problem? I guess maybe add some class
> hierarchy-awareness to findTargetMethod()?
> 
> Thanks!
> -Simon

-- 
Daniel Kulp
[email protected]
http://dankulp.com/blog
Talend - http://www.talend.com

Reply via email to