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 09:38:03 -0500

Hi Jakub,

I did not understand what you want me to try. The request entity needs
to be a RemoveObjectsRequest element. In my JAXB generated bindings
there are the following classes:

public class RegistryRequestType {
     ...
}

public class RemoveObjectsRequest extends RegistryRequestType {
     ...
}

In my resource method I expect RegistryRequestType param to have the
specific sub-type of RegistryRequestType (e.g. RemoveObjectsRequest)
based on the element that was in teh request entity.

With that summary what were you suggesting I try? Also, why is my
assumption on expected behavior incorrect? It seems to make sense that
jersey server should be able to unmarshall a RemoveObjectsRequest type
and pass it as a RegistryRequestType to my resource method.

Thank you for your kind help.

On 11/08/2011 08:31 AM, Jakub Podlesak wrote:
> Possibly. Do you have any chance to try out with the same type,
> ideally just RemoveObjectsRequest?
>
> ~Jakub
>
> On 8.11.2011 13:27, Farrukh Najmi wrote:
>> 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