users@jersey.java.net

Re: RE: array handling in JAXB to JSON conversion

From: Bo Xu <bobxu1128_at_gmail.com>
Date: Tue, 6 Jul 2010 13:27:00 -0700 (PDT)

"Yes, there are some at the moment. The issue is
i do not see a way how to force JAXB to generate <items/> tag
when the list is null without an annoying nillable="true" attribute
(i do not recall the exact name of the attribute, it might be a bit
different)
And then the attribute makes it to the JSON, and you would end up with
something like {"items":[{"nillable":true}]} for en empty array.
I am thinking about fixing this by filtering the attribute out when
serializing JSON. Another improvement would be needed to serialize
"items":[] instead of "items":null. "

Has this "Another improvement would be needed to serialize
"items":[] instead of "items":null." been done ?


Jakub Podlesak wrote:
>
> On Wed, Mar 11, 2009 at 12:45:33PM -0600, Andrew Ochsner wrote:
>> Thanks I'll take a look, though quickly looking through it it's very
>> familiar from where we were (manually creating the JSONObject) and we
>> were
>> trying to move away from that.
>
> You are right. I just wanted to provide you with a quick hack and was not
> sure you were aware of the JSONObject low-level approach.
>
>>
>> Seems were hitting up against some limitations with the JAXB approach
>
> Yes, there are some at the moment. The issue is
> i do not see a way how to force JAXB to generate <items/> tag
> when the list is null without an annoying nillable="true" attribute
> (i do not recall the exact name of the attribute, it might be a bit
> different)
> And then the attribute makes it to the JSON, and you would end up with
> something like {"items":[{"nillable":true}]} for en empty array.
> I am thinking about fixing this by filtering the attribute out when
> serializing JSON. Another improvement would be needed to serialize
> "items":[] instead of "items":null.
>
> I will probably look at the code and see what could be done
> to improve things.
>
> ~Jakub
>
>
>>
>> On Wed, Mar 11, 2009 at 12:21 PM, Jakub Podlesak
>> <Jakub.Podlesak_at_sun.com>wrote:
>>
>> > On Wed, Mar 11, 2009 at 09:39:07AM -0600, Andrew Ochsner 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
>> >
>> > the "items":[] is currently not achievable unfortunatelly (only
>> > "items":null)
>> > via the JAXB way
>> >
>> > Anyway, please see attached zip for a simple project containing
>> slightly
>> > updated classes, which produces the following (after mvn clean compile
>> > exec:java):
>> >
>> > %curl -Haccept:application/json http://localhost:9998/items/empty
>> > {"items":[]}
>> >
>> > %curl -Haccept:application/json http://localhost:9998/items/non-empty
>> > {"items":[{"field1":"jaga","field2":"baba"}]}
>> >
>> >
>> > XML is there as well, but with a slightly different format, than what
>> you
>> > requested
>> > i have not spend time on fixing it, since i understand it is not a big
>> > issue for you:
>> >
>> >
>> > %curl -Haccept:application/xml http://localhost:9998/items/empty
>> > <?xml version="1.0" encoding="UTF-8"
>> > standalone="yes"?><itemList><items/></itemList>
>> >
>> > %curl -Haccept:application/xml http://localhost:9998/items/non-empty
>> > <?xml version="1.0" encoding="UTF-8"
>> >
>> standalone="yes"?><itemList><items><items><field1>jaga</field1><field2>baba</field2></items></items></itemList>
>> >
>> >
>> > HTH,
>> >
>> > ~Jakub
>> >
>> > >
>> > > 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
>> > > >
>> > > >
>> >
>> > ---------------------------------------------------------------------
>> > 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
>
>
>
-- 
View this message in context: http://jersey.576304.n2.nabble.com/array-handling-in-JAXB-to-JSON-conversion-tp2417653p5262316.html
Sent from the Jersey mailing list archive at Nabble.com.