users@jersey.java.net

[Jersey] Re: Problem unmarshalling entity to correct JAXB object

From: Farrukh Najmi <farrukh_at_wellfleetsoftware.com>
Date: Mon, 07 Nov 2011 10:15:55 -0500

On 11/07/2011 09:18 AM, Farrukh Najmi wrote:
> Hi Guys,
>
> I have an XML Schema as follows:
>
> <complexType name="RegistryRequestType">
> ...
> </complexType>
>
> <element name="RemoveObjectsRequest">
> <complexType>
> <complexContent>
> <extension base="rs:RegistryRequestType">
> ....
> </extension>
> </complexContent>
> </complexType>
>
> I use JAXB to generate bindings for above schema as follows:
>
> public class RegistryRequestType {
> ...
> }
>
> public class RemoveObjectsRequest extends RegistryRequestType {
> ...
> }
>
> I have a jersey server resource method as follows:
>
> @PUT
> @Consumes({"application/xml"})
> @Produces({"application/xml"})
> @Path("/requests")
> public Response putRequest(RegistryRequestType req) {
> }
>
> I issue a client PUT request where entity is a RemoveObjectsRequest
> element using following code:
>
> RemoveObjectsRequest removeRequest = ...
> ClientResponse resp = webResource.accept(MediaType.APPLICATION_XML).
> type(MediaType.APPLICATION_XML).
> entity(BindingUtility.marshalObject(removeRequest)).
> //marshalls RemoveObjectsRequest object to String
> put(ClientResponse.class);
>
> When my putRequest() resource method is called, I expect the req param
> to be set to an object of type RemoveObjectsRequest. Instead it is set
> to a an object where the type is RegistryRequestType and data members
> of the RemoveObjectsRequest are not set.
>
> Is this a issue in jersey (note I am using 1.10) or do I have faulty
> assumption on what to expect?
>
> If the expected behavior is not possible then what is the way to get
> the raw entity from the request within my resource method so I can
> unmarshall it as needed.
>
> Thank you for your help.
>

I was able to workaround the issue by specifying a String param in my
resource method for receiving the request entity. I then used my JAXB
unmarshaller to unmarshall from a StringReader created with that String.

     @PUT
     @Consumes({"application/xml"})
     @Produces({"application/xml"})
     @Path("/requests")
     public Response putRequest(String entityStr) {
         try {
             StringReader reader = new StringReader(entityStr);
             Unmarshaller u = ...;
             RegistryRequestType req = (RegistryRequestType)
u.unmarshal(reader);

             //The req object is now correctly an instance of
RemoveObjectsRequest

             ...
             return response;
         } catch (JAXBException ex) {
             ...
         }
     }


I am still curious why the behavior I expected is not what jersey server
does.

-- 
Regards,
Farrukh Najmi
Web: http://www.wellfleetsoftware.com