users@jersey.java.net

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

From: Farrukh Najmi <farrukh_at_wellfleetsoftware.com>
Date: Tue, 08 Nov 2011 07:27:38 -0500

Hi Jakub,

At the beginin of this thread I mentioned that RemoveObjectsRequest
extends RegistryRequestType. Therefor I assumed that it was OK to pass a
RemoveObjectsRequest where the resource method is expecting a
RegistryRequestType. Am I wrong in this assumption?

On 11/08/2011 03:44 AM, Jakub Podlesak wrote:
> Hi Farrukh,
>
> please see in lines...
>
> On 7.11.2011 21:09, Farrukh Najmi wrote:
>>
>> Hi Jakub,
>>
>> There does not seem to be any difference whether I do either of the
>> following on client side:
>>
>> RemoveObjectsRequest removeRequest = ...;
>
> The above removeRequest is of the *RemoveObjectsRequest* type
>
>> ClientResponse resp =
>> webResource.accept(MediaType.APPLICATION_XML).
>> type(MediaType.APPLICATION_XML).
>> entity(removeRequest).
>
> and is passed here to the client
>
>> 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)
>
> while above you are consuming *RegistryRequestType*, you mention this
> also in the following line.
> My suggestion was to try sending and consuming the very same type.
>
> ~Jakub
>
>>
>> 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