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 15:09:37 -0500

Hi Jakub,

There does not seem to be any difference whether I do either of the
following on client side:

RemoveObjectsRequest removeRequest = ...;
ClientResponse resp =
     webResource.accept(MediaType.APPLICATION_XML).
     type(MediaType.APPLICATION_XML).
     entity(removeRequest).
     put(ClientResponse.class);

Or.

ClientResponse resp =
     webResource.accept(MediaType.APPLICATION_XML).
     type(MediaType.APPLICATION_XML).
     entity(BindingUtility.marshalObject(removeRequest)). //marshalls
RemoveObjectsRequest object to a String
     put(ClientResponse.class);

In both cases if the resource method signature is:

public Response putRequest(RegistryRequestType req)

then I get a RegistryRequestType instance rather than a
RemoveObjectsRequest instance.

The workaround I did on the server side to change the method signature to:

public Response putRequest(String entityStr);

and then unmarshalling from string manually works in both cases.

This is not high priority but I am curious why this does not work as
expected. Making a reproducable test case is not trivial but I would be
glad to help debug this further if you think it could be an issue that
needs filiing and eventual fixing.

Thanks very much for your help.

On 11/07/2011 11:41 AM, Jakub Podlesak wrote:
> Hi Farrukh,
>
> The problem was that on the client side you referred to your own
> BindingUtility to serialize
> the XML for you, while on the server side you expected Jersey to
> automatically
> pick up whatever the BindingUtility produced.
>
> What happens if you directly passed a RegistryRequestType to the web
> resource entity method on the client side?
> I presume that should work all right for you...
>
> ~Jakub
>
>
> On 7.11.2011 16:15, Farrukh Najmi wrote:
>> 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