Jsonj: a new library for working with JSon in Java

Update 11 July 2011: I’ve done several commits on github since announcing the project here. New features have been added; bugs have been fixed; you can find jsonj on maven central now as well; etc. In short, head over to github for the latest on this.

I’ve just uploaded a weekend project to github. So, here it is, jsonj. Enjoy.

If you read my post on json a few weeks ago, you may have guessed that I’m not entirely happy with the state of json in Java relative to other languages that come with native support for json. I can’t fix that entirely but I felt I could do a better job than most other frameworks I’ve been exposed to.

So, I sat down on Sunday and started pushing this idea of just taking the Collections framework and combining that with the design of the Json classes in GSon, which I use at work currently, and throwing in some useful ideas that I’ve applied at work. The result is a nice, compact little framework that does most of what I need it to do. I will probably add a few more features to it and expand some of the existing ones. I use some static methods at work that I can probably do in a much nicer way in this framework.

Here is some example usage (note, this will likely not stay in sync with the code in github, check there for latest version):

Updated to version 0.3, check here for latest version

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
 * Copyright (c) 2011, Jilles van Gurp
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package org.jsonj;
 
import static org.jsonj.tools.JsonBuilder.array;
import static org.jsonj.tools.JsonBuilder.nullValue;
import static org.jsonj.tools.JsonBuilder.object;
import static org.jsonj.tools.JsonBuilder.primitive;
import static org.jsonj.tools.JsonSerializer.serialize;
import static org.jsonj.tools.JsonSerializer.write;
import static org.testng.Assert.assertTrue;
 
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.LinkedList;
 
import org.jsonj.tools.JsonParser;
import org.testng.annotations.Test;
 
/**
 * Not really a test but a nice place to show off some how to use this.
 */
@Test
public class ShowOffTheFramework {
 
	/** this could be a singleton or a spring injected object, threadsafe of course. */
	private final JsonParser jsonParser = new JsonParser();;
 
	public void whatCanThisBabyDo() throws IOException {
		JsonObject object = object()
			.put("its", "just a hash map")
			.put("and", array(
				primitive("adding"),
				primitive("stuff"),
				object().put("is", "easy").get(),
				array("another array")))
			.put("numbers", 42)
			.put("including_this_one", 42.0)
			.put("booleanstoo", true)
			.put("nulls_if_you_insist", nullValue())
			.put("a", object().put("b", object().put("c", true).put("d", 42).put("e", "hi!").get()).get())
			.put("array",
				array("1", "2", "etc", "varargs are nice")).get();
 
		assertTrue(object instanceof LinkedHashMap, "JsonObject actually extends LinkedHashMap");
 
		// get with varargs, a natural evolution for Map
		assertTrue(object.get("a","b","c").asPrimitive().asBoolean(), "extract stuff from a nested object");
		assertTrue(object.getBoolean("a","b","c"), "or like this");
		assertTrue(object.getInt("a","b","d") == 42, "or an integer");
		assertTrue(object.getString("a","b","e").equals("hi!"), "or a string");
 
		assertTrue(object.getArray("array").isArray(), "works for arrays as well");
		assertTrue(object.getObject("a","b").isObject(), "and objects");
 
		// builders are nice, but still feels kind of repetitive
		JsonObject anotherObject = object.getOrCreateObject("1","2","3","4");
		anotherObject.put("5", "xxx");
		assertTrue(object.getString("1","2","3","4","5").equals("xxx"),"yep, we just added a string value 5 levels deep");
		JsonArray anotherArray = object.getOrCreateArray("5","4","3","2","1");
		anotherArray.add("xxx");
		assertTrue(object.getArray("5","4","3","2","1").contains("xxx"),"naturally works for arrays too");
 
		// Lets do some other stuff
		assertTrue(object.equals(object),
			"equals is implemented as a deep equals");
		assertTrue(array("a", "b").equals(array("b", "a")),
			"mostly you shouldn't care about the order of stuff in json");
		assertTrue(
			object().put("a", 1).put("b", 2).get()
			.equals(
				object().put("b", 2).put("a", 1).get()),
			"true for objects as well");
 
		// Arrays are lists
		JsonArray array = array("foo", "bar");
		assertTrue(array instanceof LinkedList, "JsonArray extends LinkedList");
		assertTrue(array.get(1) == array.get("bar"), "returns the same object");
		assertTrue(array.contains("foo"), "obviously");
		assertTrue(array.contains(primitive("foo")), "but this works as well");
 
		// serialize like this
		String serialized = serialize(object);
 
		// parse it
		JsonElement json = jsonParser.parse(serialized);
 
		// and write it straight to some stream
		write(System.out, json, false);
 
		// or pretty print it like this
		System.out.println("\n" + serialize(json, true));
	}
}

3 Replies to “Jsonj: a new library for working with JSon in Java”

  1. Hi,

    I’m currently facing these issues on a platform that I want to design data-driven and not model-driven.
    I love this concept and I’m whiling to try, my problem is that I also would like to use the jboss JAX-RS “magic” to setup the server side with XML and JSON (and EJB like with some more annotations) and process the communication issue.
    Do you have any suggestion on how to use jsonj and don’t loose the freedom of JAX-RS? Or any other good solution?

    Regards

    1. Good to hear!

      With most Jax RS implementations you should be able to implement your own json handlers for requests and responses. So, all you’d need is a request handler that parses the JsonElement for mime-type application/json and then a response handler that serializes to the output stream. It’s been a while but I remember doing this a few years ago with spring mvc and with resteasy.

      BTW. be sure to get the latest version on Github (1.28). I haven’t pushed to maven central for quite some time.

Leave a Reply