JSON Type | Class |
Object | JSON.Object |
Array | JSON.Array |
String | JSON.String |
Numeric | JSON.Numeric |
True | JSON.TRUE |
False | JSON.FALSE |
Null | JSON.NULL |
JSON Type | Class |
Object | JSON.Object |
Array | JSON.Array |
String | JSON.String |
Numeric | JSON.Numeric |
True | JSON.TRUE |
False | JSON.FALSE |
Null | JSON.NULL |
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.0Advanced topic:
// formats a object into a json string with indents for debug. JSON json = new JSON(); json.setPrettyPrint(true); String pretty = json.format(o); //uses Reader/InputStream Bar bar = JSON.decode(new FileInputStream("bar.json"), Bar.class); Bar bar = JSON.decode(new FileReader("bar.json"), Bar.class);
java type | json type |
---|---|
java.util.Map | object |
java.lang.Object (public property or field) | |
java.lang.Object[] | array |
java.util.Collection | |
boolean[], short[], int[], long[], float[], double[] | |
java.lang.CharSequence | string |
char[] | |
java.lang.Character | |
char | |
java.util.TimeZone | |
java.util.regex.Pattern | |
java.lang.reflect.Type | |
java.lang.reflect.Member | |
java.net.URI | |
java.net.URL | |
byte[] | string (base64) |
java.util.Locale | string (language-country) |
java.lang.Number | number |
byte, short, int, long, float, double | |
java.util.Date | number (milliseconds since 1970) |
java.util.Calendar | |
java.lang.Boolean | true/false |
boolean | |
null | null |
json type | java type |
---|---|
object | java.util.LinkedHashMap |
array | java.util.ArrayList |
string | java.lang.String |
number | java.math.BigDecimal |
true/false | java.lang.Boolean |
null | null |
object ==> Map array ==> Object[] number ==> Double or Long string ==> String null ==> null bool ==> BooleanThe java to JSON mapping is:
String --> string Number --> number Map --> object List --> array Array --> array null --> null Boolean--> boolean Object --> string (dubious!)The interface {@link JSON.Convertible} may be implemented by classes thatwish to externalize and initialize specific fields to and from JSON objects. Only directed acyclic graphs of objects are supported. The interface {@link JSON.Generator} may be implemented by classes that knowhow to render themselves as JSON and the {@link #toString(Object)} methodwill use {@link JSON.Generator#addJSON(Appendable)} to generate the JSON.The class {@link JSON.Literal} may be used to hold pre-generated JSON object. The interface {@link JSON.Convertor} may be implemented to provide staticconverters for objects that may be registered with {@link #registerConvertor(Class,Convertor)}. These converters are looked up by class, interface and super class by {@link #getConvertor(Class)}. If a JSON object has a "class" field, then a java class for that name is loaded and the method {@link #convertTo(Class,Map)} is used to find a{@link JSON.Convertor} for that class. If a JSON object has a "x-class" field then a direct lookup for a {@link JSON.Convertor} for that class name is done (without loading the class).
This class provides some static methods to convert POJOs to and from JSON notation. The mapping from JSON to java is:
object ==> Map array ==> Object[] number ==> Double or Long string ==> String null ==> null bool ==> Boolean
The java to JSON mapping is:
String --> string Number --> number Map --> object List --> array Array --> array null --> null Boolean--> boolean Object --> string (dubious!)
The interface {@link JSON.Convertible} may be implemented by classes that wish to externalize and initialize specific fields to and from JSON objects. Only directed acyclic graphs of objects are supported.
The interface {@link JSON.Generator} may be implemented by classes that know how to render themselves as JSON andthe {@link #toString(Object)} method will use {@link JSON.Generator#addJSON(StringBuffer)} to generate the JSON.The class {@link JSON.Literal} may be used to hold pre-gnerated JSON object.
The interface {@link Convertor} may be implemented to provide static convertors for objects that may be registered with {@link #registerConvertor(Class,org.mortbay.util.ajax.JSON.Convertor)}. These convertors are looked up by class, interface and super class by {@link #getConvertor(Class)}.
@author gregw
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|