users@jersey.java.net

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

From: Jakub Podlesak <jakub.podlesak_at_oracle.com>
Date: Tue, 08 Nov 2011 09:44:08 +0100

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.
>>>
>>
>
>