Ruben Laguna's blog

Oct 9, 2007 - 2 minute read - dojo flexjson java javascript json output serialize xstream

Dojo, JSON, Xstream and FLEXJSON

I’ve been trying to use XStream to generate JSON to be consumed by Dojo. But I can’t find the way to generate the right JSON from XStream, it keeps adding extraneous {} around. I even tried this but no luck . For example I want to generate this JSON output (taken from Dojo FilteringSelect example) :

{"identifier":"abbreviation",
 "items": [
   {"name":"Alaska", "label":"Alaska","abbreviation":"AK"},
   {"name":"Wyoming", "label":"Wyoming","abbreviation":"WY"}
]}

My attempt usign XStream:

package com.rubenlaguna.json;

import java.util.ArrayList;
import java.util.Collection;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;

class ItemCollection {
  public String identifier;
  public Collection<Item> items = new ArrayList<Item>();

  public ItemCollection(String identifier) {
    this.identifier = identifier;
  }

  public boolean add(Item arg0) {
    return items.add(arg0);
  }
}

class Item {
  public String name;
  public String label;
  public String abbreviation;

  public Item(String name, String label, String abbreviation) {
    this.name = name;
    this.label = label;
    this.abbreviation = abbreviation;
  }
}

public class WriteXStreamDojoTest {

  public static void main(String[] args) {
    ItemCollection itemCollection = new ItemCollection("abbreviation");
    itemCollection.add(new Item("Alaska","Alaska","AK"));
    itemCollection.add(new Item("Wyoming","Wyoming","WY"));

    XStream xstream = new XStream(new JettisonMappedXmlDriver());
    String erroneousJsonStr = xstream.toXML(itemCollection);
    System.out.println(erroneousJsonStr);
  }
}

resulted in the following JSON Output (i added some space and breaklines for readability):

{"com.rubenlaguna.json.ItemCollection":
  {"identifier":"abbreviation",
   "items": {
     "list": [
       {"name": "Alaska", "label": "Alaska", "abbreviation": "AK"},
       {"name": "Wyoming", "label": "Wyoming", "abbreviation": "WY"},
     ]
   }
  }
}

I couldn’t figure out how to get XStream to output the desired JSON. The main issue is that I couldn’t make “items” a simple JSON array, it always end up as an object with an array in it. So I decided to give out a try to FLEXJSON. I really found much easier to control the output with this tool. I guess that XStream is more focused on serialization/deserialization and doesn’t allow customization without relaying in custom converters (I didn’t walk that road, too much work). Here is the example source code (also as a gist) using FLEXJSON:

package com.rubenlaguna.json.flexjson;

import flexjson.JSONSerializer;

public class WriteFlexjsonDojoTest {

  public static void main(String[] args) {
    ItemCollection itemCollection = new ItemCollection("abbreviation");
    itemCollection.add(new Item("Alaska", "Alaska", "AK"));
    itemCollection.add(new Item("Wyoming", "Wyoming", "WY"));

    JSONSerializer serializer = new JSONSerializer().include("items").exclude("*.class");
    String correctJsonStr = serializer.serialize(itemCollection);
    System.out.println(correctJsonStr);

  }

}

that yields the following correct result:

{"identifier":"abbreviation",
  "items":[
    {"name":"Alaska","label":"Alaska","abbreviation":"AK"},
    {"name":"Wyoming","label":"Wyoming","abbreviation":"WY"}
  ]
}