Ruben Laguna’s blog

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) :

1
2
3
4
5

1
2
3
4
5
<span class='line'>{identifier:"abbreviation",
</span><span class='line'>items: [
</span><span class='line'>	{name:"Alaska", label:"Alaska",abbreviation:"AK"},
</span><span class='line'>	{name:"Wyoming", label:"Wyoming",abbreviation:"WY"}
</span><span class='line'>]}</span>

My attempt usign XStream:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<span class='line'>package com.rubenlaguna.json;
</span><span class='line'>
</span><span class='line'>import java.util.ArrayList;
</span><span class='line'>import java.util.Collection;
</span><span class='line'>
</span><span class='line'>import com.thoughtworks.xstream.XStream;
</span><span class='line'>import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
</span><span class='line'>
</span><span class='line'>class ItemCollection {
</span><span class='line'>	public String identifier;
</span><span class='line'>	public Collection&lt;Item> items = new ArrayList&lt;Item>();
</span><span class='line'>
</span><span class='line'>	public ItemCollection(String identifier) {
</span><span class='line'>		this.identifier = identifier;
</span><span class='line'>	}
</span><span class='line'>
</span><span class='line'>	public boolean add(Item arg0) {
</span><span class='line'>		return items.add(arg0);
</span><span class='line'>	}
</span><span class='line'>
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>class Item {
</span><span class='line'>	public String name;
</span><span class='line'>	public String label;
</span><span class='line'>	public String abbreviation;
</span><span class='line'>
</span><span class='line'>	public Item(String name, String label, String abbreviation) {
</span><span class='line'>		this.name = name;
</span><span class='line'>		this.label = label;
</span><span class='line'>		this.abbreviation = abbreviation;
</span><span class='line'>	}
</span><span class='line'>
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>public class WriteXStreamDojoTest {
</span><span class='line'>
</span><span class='line'>	public static void main(String[] args) {
</span><span class='line'>		ItemCollection itemCollection = new ItemCollection("abbreviation");
</span><span class='line'>		itemCollection.add(new Item("Alaska","Alaska","AK"));
</span><span class='line'>		itemCollection.add(new Item("Wyoming","Wyoming","WY"));
</span><span class='line'>		
</span><span class='line'>		XStream xstream = new XStream(new JettisonMappedXmlDriver());
</span><span class='line'>		String erroneousJsonStr = xstream.toXML(itemCollection);
</span><span class='line'>		System.out.println(erroneousJsonStr);
</span><span class='line'>
</span><span class='line'>	}
</span><span class='line'>
</span><span class='line'>}</span>

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

1
2
3
4
5
6
7
8
9
10

1
2
3
4
5
6
7
8
9
10
<span class='line'>{"com.rubenlaguna.json.ItemCollection":
</span><span class='line'>       {"identifier":"abbreviation",
</span><span class='line'>         "items":{ "@class":"list",
</span><span class='line'>                      "com.rubenlaguna.json.Item":[  
</span><span class='line'>                         {"name":"Alaska","label":"Alaska","abbreviation":"AK"},
</span><span class='line'>                         {"name":"Wyoming","label":"Wyoming","abbreviation":"WY"}
</span><span class='line'>                       ]
</span><span class='line'>                   }
</span><span class='line'>      }
</span><span class='line'>}</span>

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<span class='line'>package com.rubenlaguna.json.flexjson;
</span><span class='line'>
</span><span class='line'>import flexjson.JSONSerializer;
</span><span class='line'>
</span><span class='line'>public class WriteFlexjsonDojoTest {
</span><span class='line'>
</span><span class='line'>	public static void main(String[] args) {
</span><span class='line'>		ItemCollection itemCollection = new ItemCollection("abbreviation");
</span><span class='line'>		itemCollection.add(new Item("Alaska", "Alaska", "AK"));
</span><span class='line'>		itemCollection.add(new Item("Wyoming", "Wyoming", "WY"));
</span><span class='line'>
</span><span class='line'>		JSONSerializer serializer = new JSONSerializer().include("items").exclude("*.class");
</span><span class='line'>		String correctJsonStr = serializer.serialize(itemCollection);
</span><span class='line'>		System.out.println(correctJsonStr);
</span><span class='line'>
</span><span class='line'>	}
</span><span class='line'>
</span><span class='line'>}</span>

that yields the following correct result:

1
2
3
4

1
2
3
4
<span class='line'>{"identifier":"abbreviation",
</span><span class='line'>  "items":[ {"name":"Alaska","label":"Alaska","abbreviation":"AK"},
</span><span class='line'>              {"name":"Wyoming","label":"Wyoming","abbreviation":"WY"}
</span><span class='line'>            ]}</span>

Comments

Copyright © 2015 - Ruben Laguna - Powered by Octopress