A JSON entity can be one of several things: an object (set of name/Json entity pairs), an array (a list of other JSON entities), a string, a number, a boolean or null. All of those are represented as Json
instances. Each of the different types of entities supports a different set of operations. However, this class unifies all operations into a single interface so in Java one is always dealing with a single object type: this class. The approach effectively amounts to dynamic typing where using an unsupported operation won't be detected at compile time, but will throw a runtime {@link UnsupportedOperationException}. It simplifies working with JSON structures considerably and it leads to shorter at cleaner Java code. It makes much easier to work with JSON structure without the need to convert to "proper" Java representation in the form of POJOs and the like. When traversing a JSON, there's no need to type-cast at each step because there's only one type: Json
.
One can examine the concrete type of a Json
with one of the isXXX
methods: {@link #isObject()}, {@link #isArray()}, {@link #isNumber()}, {@link #isBoolean()}, {@link #isString()}, {@link #isNull()}.
The underlying representation of a given Json
instance can be obtained by calling the generic {@link #getValue()} method or one of the asXXX
methods such as {@link #asBoolean()} or {@link #asString()} etc. JSON objects are represented as Java {@link Map}s while JSON arrays are represented as Java {@link List}s. Because those are mutable aggregate structures, there are two versions of the corresponding asXXX
methods: {@link #asMap()} which performs a deep copy of the underlyingmap, unwrapping every nested Json entity to its Java representation and {@link #asJsonMap()} whichsimply return the map reference. Similarly there are {@link #asList()} and {@link #asJsonList()}.
There are several static factory methods in this class that allow you to create new Json
instances:
{@link #read(String)} | Parse a JSON string and return the resulting Json instance. The syntax recognized is as defined in http://www.json.org. |
{@link #make(Object)} | Creates a Json instance based on the concrete type of the parameter. The types recognized are null, numbers, primitives, String, Map, Collection, Java arrays and Json itself. |
{@link #nil()} | Return a Json instance representing JSON null . |
{@link #object()} | Create and return an empty JSON object. |
{@link #object(Object)} | Create and return a JSON object populated with the key/value pairs passed as an argument sequence. Each even parameter becomes a key (via toString ) and each odd parameter is converted to a Json value. |
{@link #array()} | Create and return an empty JSON array. |
{@link #array(Object)} | Create and return a JSON array from the list of arguments. |
If a Json
instance is an object, you can set its properties by calling the {@link #set(String,Object)} method which will add a new property or replace an existing one.Adding elements to an array Json
is done with the {@link #add(Object)} method.Removing elements by their index (or key) is done with the {@link #delAt(int)} (or{@link #delAt(String)}) method. You can also remove an element from an array without knowing its index with the {@link #remove(Object)} method. All these methods return the Json
instance being manipulated so that method calls can be chained. If you want to remove an element from an object or array and return the removed element as a result of the operation, call {@link #atDel(int)} or {@link #atDel(String)} instead.
If you want to add properties to an object in bulk or append a sequence of elements to array, use the {@link #with(Json)} method. When used on an object, this method expects anotherobject as its argument and it will copy all properties of that argument into itself. Similarly, when called on array, the method expects another array and it will append all elements of its argument to itself.
The {@link #at(int)} method returns the array element at the specified index and the{@link #at(String)} method does the same for a property of an object instance. You canuse the {@link #at(String,Object)} version to create an object property with a defaultvalue if it doesn't exist already.
To help in navigating JSON structures, instances of this class contain a reference to the enclosing JSON entity (object or array) if any. The enclosing entity can be accessed with {@link #up()} method.
The combination of method chaining when modifying Json
instances and the ability to navigate "inside" a structure and then go back to the enclosing element lets one accomplish a lot in a single Java statement, without the need of intermediary variables. Here for example how the following JSON structure can be created in one statement using chained calls:
{"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"} ] } "position": 0 }}
import json.Json; import static json.Json.*; ... Json j = object() .at("menu", object()) .set("id", "file") .set("value", "File") .at("popup", object()) .at("menuitem", array()) .add(object("value", "New", "onclick", "CreateNewDoc()")) .add(object("value", "Open", "onclick", "OpenDoc()")) .add(object("value", "Close", "onclick", "CloseDoc()")) .up() .up() .set("position", 0) .up(); ...
If there's no danger of naming conflicts, a static import of the factory methods ( import static json.Json.*;
) would reduce typing even further and make the code more readable.
To get a compact string representation, simply use the {@link #toString()} method. If youwant to wrap it in a JavaScript callback (for JSON with padding), use the {@link #pad(String)}method.
@author Borislav Iordanov @version 1.0
|
|
|
|
|
|
|
|