users@jersey.java.net

Re: [Jersey] Unmarshaling JAXB object from JSON

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Wed, 01 Apr 2009 16:54:35 +0200

On Apr 1, 2009, at 4:45 PM, Farrukh Najmi wrote:

> Paul Sandoz wrote:
>>
>> On Apr 1, 2009, at 3:59 PM, Farrukh Najmi wrote:
>>
>>> Paul Sandoz wrote:
>>>>
>>>> On Apr 1, 2009, at 1:57 PM, Farrukh Najmi wrote:
>>>>> Hi Paul,
>>>>>
>>>>> If the jsonString represents List<PostalAddressType> where
>>>>> PostalAddressType is my JAXB generated bean then what should c
>>>>> be and how can I create an instance. Sorry for asking such a
>>>>> basic question. Also I note that the second arg to
>>>>> getMessageBodyReader is of a different type. I can get that with
>>>>> following code (thanks Marc):
>>>>>
>>>>> GenericEntity<List<PostalAddressType>> entityPostalAddresses =
>>>>> new
>>>>> GenericEntity<List<PostalAddressType>>(listPostalAddresses) {};
>>>>> Type genericTypePostalAddresses = entityPostalAddresses.getType();
>>>>>
>>>>> So my call looks like:
>>>>>
>>>>> providers.getMessageBodyReader(??, genericTypePostalAddresses,
>>>>> (java.lang.annotation.Annotation[])null, "application/json");
>>>>>
>>>>> and I am unsure how to get the first param in the call.
>>>>>
>>>>
>>>
>>> I just realized that the formParams are returned in a
>>> MultiValuedMap where the key PostalAddress has a List<String>
>>> value which looks like below when using MultiValuedMap.toString()
>>>
>>> PostalAddress=[{streetNumber:"65",street:"Marla
>>> Ln
>>> .",stateOrProvince
>>> :"MA",postalCode:"01867",country:"USA",city:"Reading"},
>>> {streetNumber:"1",street:"Main
>>> St
>>> .",stateOrProvince
>>> :"MA",postalCode:"01867",country:"USA",city:"Reading"}]
>>>
>>> So I have a List<String> that I need to convert to
>>> List<PostalAddressType> where PostalAddressType is the JAXB
>>> generated bean class.
>>>
>>
>> The List<String> is returned because there could be more than one
>> form parameter "PostalAddress" declared. It is the same for query
>> parameters e.g. http://host:8080/path?a=one&a=two
>>
>> If you like you can also use:
>>
>> @FormParam("PostalAddress") String postalAddress
>>
>> or
>>
>> @FormParam("PostalAddress") List<String> postalAddresses
>>
>> the former will obtain the first parameter value for the parameter
>> name "PostalAddress", where as the latter will obtain all values.
>
> I do have multiple values that need to be supported so the latter of
> above is what I am using.
>
>
>>
>>
>>> Does this mean that I need to convert each String in List<String>
>>> to PostalAddressType or can I convert List<String> to convert to
>>> List<PostalAddressType> directly?
>>>
>>
>> The former.
>
> OK so my code now looks like this:
>
> List<String> postalAddresses = ...
> for (String postalAddressStr : postalAddresses) {
> MessageBodyReader r =
> providers.getMessageBodyReader(PostalAddressType.class,
> PostalAddressType.class, new Annotation[1],
> MediaType.APPLICATION_JSON_TYPE);
> PostalAddressType postalAddress = (PostalAddressType)
> r.readFrom(PostalAddressType.class, PostalAddressType.class, new
> Annotation[1], MediaType.APPLICATION_JSON_TYPE,
> new InBoundHeaders(),
> new ByteArrayInputStream(postalAddressStr.getBytes()));
> org.getPostalAddress().add(postalAddress);
> }
>
> I am now getting following exception:
>
> java.lang.UnsupportedOperationException: Not supported yet.
> at
> com
> .sun
> .jersey.json.impl.JSONUnmarshaller.unmarshal(JSONUnmarshaller.java:
> 175)
> at
> com
> .sun
> .jersey
> .json
> .impl
> .provider
> .entity
> .JSONRootElementProvider.readFrom(JSONRootElementProvider.java:119)
> at
> com
> .sun
> .jersey
> .core
> .provider
> .jaxb
> .AbstractRootElementProvider
> .readFrom(AbstractRootElementProvider.java:97)
>

That is definitely a bug with unmarshalling JAXB XML type beans. Can
you log an issue? I had a look to see if there is an obvious fix but
could not work it out. Need Jakub!

Try using a JAXB element bean, annotated with XmlRootElement.

Paul.