users@jaxb.java.net

Re: Rendering Collection<T> objects to JSON

From: Wolfgang Laun <wolfgang.laun_at_gmail.com>
Date: Tue, 7 Apr 2009 09:33:37 +0200

Isn't this more a JSON problem than a JAXB problem? Marshalling this
to XML should certainly always result in the same XML element nesting,
irrespective of the number of elements in the collection.

Curious as I am, I've peeked at the JSON syntax and examples. From one
of the latter, it appears to me that JSON's
   "tag":[ {,,,}...{...} ]
is/has to be used for attaching the "tag" to all the anonymous items
between '[' and ']'. If there is only one item, there's no need for
the []-pair. It seems that the receiver has to get() the elements of a
collection, and to check dynamically whether it's a simple object
(JSONObject) or an array (JSONArray). - But you might discuss this
with the JSON buffs.

-W


On 4/7/09, Richard Bailey <rbailey_at_gatech.edu> wrote:
> Hi guys, I'm not sure if this is a bug or a misconfiguration somewhere on my
> part. I'm using JAXB to do object marshalling to JSON when creating a
> response to a REST API I'm building. I've structured each of my responses
> to contain an error field and a payload field.
>
> In general everything works fine but when I want to return a list of items
> I'm seeing the following behavior and it feels like a bug... When I set the
> payload to be a converter which has a list with more than one element it's
> returned as an array of json encoded objects. When the list has one element
> though it's returning a single encoded object instead of a single element
> array despite the object having type Collection<T>.
>
> I've pulled out everything from the nested coverter object for testing and
> and included sample output from the same below. I'd appreciate your
> thoughts on the matter.
>
> Thanks
> -Richard
>
> Code:
> @XmlRootElement(name = "userDevices")
> public class UserDevicePayload {
> public void setDevice(List<UserDevice> l) {
> deviceList = l;
> }
>
> @XmlElement
> public Collection<UserDevice> getDevice() {
> return deviceList;
> }
>
> private List<UserDevice> deviceList;
> }
>
>
> @Provider
> public final class JAXBContextResolver implements
> ContextResolver<JAXBContext> {
>
> private final JAXBContext context;
>
> private final Set<Class> types;
>
> private final Class[] cTypes = {
> WaiUsersConverter.class,
> WaiUserConverter.class,
> UriResolver.class,
> WaiUserlocationsConverter.class,
> WaiUserlocationConverter.class,
> WatchDetailsPayloadConverter.class,
> WatchDetailsPayloadConverter.class,
> ErrorConverter.class};
>
> public JAXBContextResolver() throws Exception {
> this.types = new HashSet(Arrays.asList(cTypes));
> this.context = new
> JSONJAXBContext(JSONConfiguration.mapped().rootUnwrapping(false).build(),
> cTypes);
> }
>
> public JAXBContext getContext(Class<?> objectType) {
> return (types.contains(objectType)) ? context : null;
> }
> }
>
> When the payload is a list with more than one item:
> {
> "error":{"code":"","message":""},
> "payload":{
> "device":[
> {
> "description":"",
> "deviceType":"GENERIC_WIFI",
> "deviceId":"3",
> "mac":"001122334455",
> "priority":"42"
> },
> {
> "description":"",
> "deviceType":"GENERIC_WIFI",
> "deviceId":"4",
> "mac":"001122334455",
> "priority":"0"
> }
> ]
> }
> }
>
>
> When the payload is a list with one item:
>
> {
> "error":{"code":"","message":""},
> "payload":{
> "device":{
> "deviceType":"LAPTOP",
> "deviceId":"1",
> "mac":"001122334455",
> "priority":"2"
> }
> }
> }
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>
>