users@jersey.java.net

Re: [Jersey] RE: array handling in JAXB to JSON conversion

From: Andrew Ochsner <aochsner_at_cs.stanford.edu>
Date: Wed, 11 Mar 2009 09:47:26 -0600

So, just a quick follow up while I was reading this...

{ "items" : [{"field1":"one", "field2:"two"}, {"field1":"one",
"field2:"two"}] }

is the format I absolutely need. XML is just nice to have, but I need JSON
in this format...

On Wed, Mar 11, 2009 at 9:39 AM, Andrew Ochsner <aochsner_at_cs.stanford.edu>wrote:

> Okay, here's ideally the scenario I have/want:
>
> I need JSON in a particular format where it looks like the following:
> { "items" : [{"field1":"one", "field2:"two"}, {"field1":"one",
> "field2:"two"}] }
> or { "items" : [] } when the list is empty
>
> I'm not too particular about the XML output as we don't have any
> requirements for it, just is a nice bonus for taking this approach, but I'll
> include them as well:
> <response>
> <item><field1>one</field1><field2>two</field2></item>
> <item><field1>one</field1><field2>two</field2></item>
> </response>
>
> and
>
> <response/> for empty list
>
> Our class looks like:
> @XmlRootElement(name = "response")
> public class Items {
> @XmlElement(name = "items")
> public List<Item> items= new ArrayList<Item>();
> }
>
> This works for when the list has 1 or more items, but returns "null" when
> the list has 0 items (instead of { "items": [] })
>
> This makes sense though when you look at the XML being produced (which is
> what the JSON is based off of). I really probably would want the XML to
> look more like:
> <response>
> <items>
> <item><field1>one</field1><field2>two</field2></item>
> <item><field1>one</field1><field2>two</field2></item>
> </items>
> </response>
>
> and
>
> <response><items/></response>
>
> So, a simple change to the class:
> @XmlElement(name = "items")
> public List<Item> items= new ArrayList<Item>();
>
> becomes
>
> @XmlElementWrapper(name = "items")
> public List<Item> items= new ArrayList<Item>();
>
> However, the JSON becomes:
>
> { "items" : [{ "item" : {"field1":"one", "field2:"two"}}, { "item" :
> {"field1":"one", "field2:"two"}}] }
> or { "items" : [ null ] } when the list is empty
>
> So it seems there are a few approaches I could take:
> 1) Add a null Item when the list is empty in order to produce some XML -
> not ideal
> 2) Enable more than just root unwrapping in the XmlElementWrapper case
> where I can unwrap the items in the list - sounds better
> 3) Try the JacksonProvider and separate JSON generation from XML
> generation... not considered this before this email...
>
> Does that make any sense? Thoughts?
> Andy O
>
>
> On Wed, Mar 11, 2009 at 5:10 AM, Jakub Podlesak <Jakub.Podlesak_at_sun.com>wrote:
>
>> On Tue, Mar 10, 2009 at 01:45:11PM -0600, Andrew Ochsner wrote:
>> > Sorry, one more unfortunate update.
>> >
>> > Using XmlElementWrapper, while gets us closer to correct JSON (and looks
>> to
>> > be correct XML) it really messes things up for us in JSON when there are
>> > elements in the array where it looks like :
>> > { "items": { "item": {}, "item":{} }
>>
>> I suppose the issue now lays in the Item bean,
>> since it's content is not being written.
>>
>> How the XML looks like?
>>
>> Could you give a quick try with something like:
>>
>> @XmlRootElement
>> public class Item {
>>
>> public String field1 = "one";
>> public String field2 = "two";
>> }
>>
>> And second thing: the JSON above is incorrect, you should not have
>> two "item" objects encapsulated in the same container object,
>> how did you get it? Default mapped convention?
>>
>> And i am also a bit confused with your desired JSON format, since
>>
>> {"items":[{"field1":"val1","field2":"val2"}] differs from
>> {"items":[{"item":{"field1":"val1","field2":"val2"}}]
>>
>> Could you please clarify? I mean, could you give us some examples
>> of JSON exprs you need to get generated?
>>
>> And the last thing: If i understand it correctly: you do need both XML and
>> JSON generated, right?
>>
>> Thanks,
>>
>> ~Jakub
>>
>>
>>
>> >
>> > So, we really have an issue here. And the hack solution really defeats
>> the
>> > purpose for us as we want to generate documentation based on the code
>> (as
>> > opposed to javadoc which can and will get out of sync). We can't infer
>> much
>> > from a Response return value.
>> >
>> > Thanks
>> > Andy O
>> >
>> > On Tue, Mar 10, 2009 at 10:20 AM, Moiz Dohadwala <
>> mdohadwala_at_mokafive.com>wrote:
>> >
>> > > Hello,
>> > >
>> > >
>> > >
>> > > Thank you all for your suggestions. I had tried out the annotations
>> > > suggested below without success prior to posting to the mailing list.
>> Right
>> > > now, due to time pressure, I have implemented the following ugly hack:
>> > >
>> > >
>> > >
>> > > If( rows.getTotalCount() == 0 )
>> > >
>> > > {
>> > >
>> > > return Response.ok(“{rows:[], totalCount:0}”).build();
>> > >
>> > > else
>> > >
>> > > {
>> > >
>> > > return Response.ok(rows).build();
>> > >
>> > > }
>> > >
>> > >
>> > >
>> > > This seems to have tied me over for now.
>> > >
>> > >
>> > >
>> > > I would suggest changes to the JSONConfiguration.arrays() api to
>> specify
>> > > forcing of the empty arrays.
>> > >
>> > >
>> > >
>> > > -Moiz
>> > >
>> > >
>> > >
>> > > *From:* aochsner_at_gmail.com [mailto:aochsner_at_gmail.com] *On Behalf Of
>> *Andrew
>> > > Ochsner
>> > > *Sent:* Tuesday, March 10, 2009 8:49 AM
>> > > *To:* users_at_jersey.dev.java.net
>> > > *Subject:* Re: [Jersey] RE: array handling in JAXB to JSON conversion
>> > >
>> > >
>> > >
>> > > So, a little update because I'm running into the same issue, except
>> I'm
>> > > using the natural mapping.
>> > >
>> > >
>> > > Various combinations of required=true/false and nillable = true/false
>> have
>> > > not helped. In fact, when getting as XML, the <items/> element is not
>> > > getting written out. So that's a JAXB thing.
>> > >
>> > > So I'm trying the XmlElementWrapper, and it's close. The XML does
>> spit out
>> > > <items/> which is good, but the JSON is { "items":[null] } which
>> doesn't
>> > > seem to be the same as { "items":[] } which is what I want.
>> > >
>> > > HTH
>> > > Andy O
>> > >
>> > > On Mon, Mar 9, 2009 at 10:39 AM, Jakub Podlesak <
>> Jakub.Podlesak_at_sun.com>
>> > > wrote:
>> > >
>> > > On Mon, Mar 09, 2009 at 05:10:19PM +0100, Paul Sandoz wrote:
>> > > > Hi Jakub,
>> > > >
>> > > > Do you mean that JAXB is not writing out any start element for
>> "items"
>> > > > because the value of the items field is null or empty?
>> > >
>> > > Hmmm, you are right, jaxb should generate at least <items/>, which
>> should
>> > > IIRC get
>> > > translated into "items":null for the default mapped convention.
>> > >
>> > > Need to check this out, and then will report back here.
>> > >
>> > > ~Jakub
>> > >
>> > >
>> > >
>> > > >
>> > > > There may be an annotation to force JAXB to always write out
>> "items":
>> > > >
>> > > > 1) using c; or
>> > >
>> > > >
>> > > > 1) using XmlElementWrapper, the JavaDoc states:
>> > > >
>> > > >
>> > >
>> http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElementWrapper.html
>> > > > The two serialized XML forms allow a null collection to be
>> represented
>> > > > either by absence or presence of an
>> > > > element with a nillable attribute.
>> > > >
>> > > > or it may be possible to utilize XmlJavaTypeAdapter.
>> > > >
>> > > > Paul.
>> > > >
>> > > > On Mar 9, 2009, at 4:47 PM, Jakub Podlesak wrote:
>> > > >
>> > > >>
>> > > >> Hi Moiz,
>> > > >>
>> > > >> You have hit an edge case, and i am afraid i have no good news for
>> you.
>> > > >> Jersey JSON provider takes what JAXB gives out, and the information
>> > > >> about the emtpy array is obviously missing.
>> > > >>
>> > > >> One option would be to try out the provider mentioned by Tatu.
>> > > >> Have you had a chance to test it yet?
>> > > >>
>> > > >> Another option would be to use the low-level JSONObect/JSONArray
>> > > >> providers (used in bookmark example [1].
>> > > >>
>> > > >> ~Jakub
>> > > >>
>> > > >> [1]
>> > >
>> http://download.java.net/maven/2/com/sun/jersey/samples/bookmark/1.0.3-SNAPSHOT/bookmark-1.0.3-SNAPSHOT-project.zip
>> > > >>
>> > > >>
>> > > >> On Fri, Mar 06, 2009 at 07:21:51AM -0800, Moiz Dohadwala wrote:
>> > > >>> I have tried that too, but hasn't worked either.
>> > > >>>
>> > > >>> -Moiz
>> > > >>>
>> > > >>> From: Wilhelmsen Tor Iver [mailto:TorIverW_at_arrive.no]
>> > > >>> Sent: Friday, March 06, 2009 5:01 AM
>> > > >>> To: users_at_jersey.dev.java.net
>> > > >>> Subject: Re: [Jersey] RE: array handling in JAXB to JSON
>> conversion
>> > > >>>
>> > > >>> Try adding required=true to this:
>> > > >>>
>> > > >>> @XmlElement(name="items")
>> > > >>> List<Item> items;
>> > > >>>
>> > > >>> or else tell JAXB to treat nulls and empty collections
>> differently. We
>> > > >>> ran into the same issue where null/empty elements were absent from
>> the
>> > > >>> XML and thus a JAXB client would generate classes missing these
>> > > >>> properties.
>> > > >>
>> > > >>
>> ---------------------------------------------------------------------
>> > > >> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> > > >> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>> > > >>
>> > > >
>> > > >
>> > > >
>> ---------------------------------------------------------------------
>> > > > To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> > > > For additional commands, e-mail: users-help_at_jersey.dev.java.net
>> > > >
>> > >
>> > > ---------------------------------------------------------------------
>> > > To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> > > For additional commands, e-mail: users-help_at_jersey.dev.java.net
>> > >
>> > >
>> > >
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>