users@jersey.java.net

Re: [Jersey] Problem with JSON array output

From: Jakub Podlesak <Jakub.Podlesak_at_Sun.COM>
Date: Tue, 25 Nov 2008 11:56:35 +0100

Hi Clark,

On Mon, Nov 24, 2008 at 03:24:14PM -0800, Clark Anthony wrote:
> I'm using Jersey 1.0 and I have a problem with the way that arrays are output in JSON. I was wondering if this is normal, or perhaps Jersey is misreading my JAXB beans?
>
> I have XML data that looks like this:
> <Contexts>
> <Context><name>One</name></Context>
> <Context<name>Two</name></Context>
> <Contexts>
>
> Since the value of Contexts is an array of Context, I would presume that the JSON would look like this:
> {"Contexts":[{"Context":{"Name":"One"}}, {"Context":{"Name":"Two"}}]}
>
> However, the JSON actually looks like this:
> {"Contexts":{"Context":[{"Name":"One"},{"Name":"Two"}]}}

which is correct behaviour, as we want to get the simplest possible JSON expression.
The wrapping <Context/> element here seems kind of redundant.

>
> Seems to me the (incorrect) XML translation of this JSON would be:
> <Contexts>
> <Context>
> <Name>One</Name>
> <Name>Two</Name>
> </Context>
> <Contexts>

It depends on how you define the translation.

>
> My JAXB Beans, which produce the correct XML are:
> @XmlRootElement(name = "Contexts")
> @XmlAccessorType(XmlAccessType.FIELD)
> public class Contexts {
> @XmlElement(name = "Context")
> protected List<ContextBean> context;
>
> public List<ContextBean> getContext() {
> if (context == null) {
> context = new ArrayList<ContextBean>();
> }
> return context;
> }
> }
> @XmlAccessorType(XmlAccessType.FIELD)
> @XmlType(name = "Context")
> public class ContextBean {
> @XmlElement(name = "Name")
> protected String name;
> public String getName() {
> return name;
> }
>
> public void setName(String name) {
> this.name = name;
> }
> }
>
> Is the JSON output actually correct, or could Jersey be misreading my "@XmlElement" tag for the Context array?
>

Jersey does what is expected here.
Is there no way to try simplify things with e.g.:

 @XmlRootElement(name = "Contexts")
 @XmlAccessorType(XmlAccessType.FIELD)
 public class Contexts {
     @XmlElement
     public List<String> names;
 }

Which would give you:

{"names":["one","two"]}

or

<Contexts><names>one</names><names>two</names></Contexts>

?


> If everything is behaving as expected, then that poses another problem for me. Using the above example, I have to pass in "Context" to the JSON_ARRAYS property in order to wrap single-element arrays. There are situations in my larger XML schema where "Context" can appear by itself (not in a List), and I do not want it to be wrapped. I would like to be able to send in "Contexts" to be wrapped as an array, but not "Context". Is this possible?

I see. Unfortunately, there is no workaround (other than changing the XML schema)
for the current and the upcomming (1.0.1) Jersey version.

However, with better JAXB integration (need to wait for JAXB 2.1.10 RI),
special configuration for single-elem arrays won't be needed any more.
This will come after Jersey 1.0.1 release.

~Jakub

>
> Thanks,
> Clark
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>