users@jersey.java.net

Re: [Jersey] Unmarshaling JAXB object from JSON

From: Jakub Podlesak <Jakub.Podlesak_at_Sun.COM>
Date: Wed, 01 Apr 2009 20:06:09 +0200

Hi Farrukh,

it seems, it is not only the format (missing double quotes at JSON keys).
Because then i am getting a different error message:

org.codehaus.jackson.JsonParseException: Unexpected character ('s' (code 115)): was expecting double-quote to start field name

The following, however, works for me fine with my own Address bean:

    @POST
    @Produces("application/json")
    public Response update(Form formData) throws IOException {

        GenericType<List<Address>> genericType =
                new GenericType<List<Address>>() {
                };

        String jsonString = formData.getFirst("la");

        MessageBodyReader<List<Address>> r = p.getMessageBodyReader(
                genericType.getRawClass(), genericType.getType(), new Annotation[0],
                MediaType.APPLICATION_JSON_TYPE);

        List<Address> b = r.readFrom(genericType.getRawClass(), genericType.getType(), new Annotation[0],
                MediaType.APPLICATION_JSON_TYPE,
                new InBoundHeaders(),
                new ByteArrayInputStream(jsonString.getBytes()));

        return Response.ok(new GenericEntity<List<Address>>(b){}).build();
    }

If you adjust to your PostalAddress bean class, would the above code work for you?

Since i do not have your bean class code, i am using just:

@XmlRootElement
public class Address {
    public String street;
    public String town;

    public Address(){}

    public Address(String street, String town) {
        this.street = street;
        this.town = town;
    }
}

and curl -d'la=[{street:"the street",town:"the town"}]' http://localhost:9998/jsonForm

for testing.

Does it help?

~Jakub


On Wed, Apr 01, 2009 at 11:41:18AM -0400, Farrukh Najmi wrote:
> Paul Sandoz wrote:
>>
>> 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.
>
> Thanks to Jakub's help it seems I may have invalid JSON string (missing
> double quotes around key/field names).
> I will investigate more before making work for dev team. Jersey project and
> team are superb! Thanks.
>
> --
> Regards,
> Farrukh
>
> Web: http://www.wellfleetsoftware.com
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>