Friday, 9 September 2011

Basic guide of JSON on Java and Android

Important: This basic guide is focusing mainly to run the Java code in Android. There might be some methods that only exists for Java. In that case, they are not included in this guide.

1. Introduction
JSON (JavaScript Object Notation) was created as lightweight text-based open standard designed for human-readable data interchange. Originally specified by Douglas Crockford, It could be used as an alternative to XML.
Because it is lightweight, it is commonly used for interchange of data between the server and the client, specially when the data traffic of the client is limited, such as the case of the mobile phones.
Here is an example of the JSON code compared with XML:

XML
<?xml version="1.0" encoding="UTF-8"?>
<email>
  <to>Konrad</to>
  <cc>Natalia</cc>
  <cc>Maria</cc>
  <from>Cristobal</from>
  <subject>An XML-JSON example</subject>
  <body>Hope this example is witty enough!</body>
</email>

JSON
{"email" : {
"to" : "Konrad",
"cc" : ["Natalia", "Maria"],
"from" : "Cristobal",
"subject" : "An XML-JSON example",
"body" : "Hope this example is witty enough!"
}}

Source: Mobile Mashups

Because JSON utilizes double quote ("") instead of tags, there is not need to repeat the tag at the end of the data, which could mean a very important amount of data traffic saved.

2. JSON in Java
2.1 Packages to import
There are several packages to import depending on the use of the data. You can obtain them in the JSON Web page. Here could be the most importants ones:
  • org.json.JSONObject
Contains the constructor and the methods to work with the basic unit of data which is JSONObject
  • org.json.JSONArray
Contains the constructor and the methods to work with an array of values of JSON (JSONObjects, JSONArrays, Strings, Booleans, Integers, Longs, Doubles, null or NULL)
  • org.json.JSONStringer
Implements the method toString(). It is not strict necessary import it because JSONObject has this methods by default.
  • org.json.JSONTokener
Followed by RFC 4627, it parse a JSON object coded as String into a JSONTokener and enable the possibility to go through the elements using methods as back() or next()
  • org.json.JSONException
JSON is able to launch its own exception. This class is implemented extending the java.lang.Exception, making possible using the try-catch sentence in Java to capture the JSON exceptions.
  • org.json.JSONString
An interface created to utilize the method toString. This class doesn't exist in Android.
  • org.json.JSONWriter
Class used to produce rapidly JSON text. This class doesn't exist in Android. 

Note: Because it is a basic guide about JSON, only the first two packages will be used to implement basic JSON examples.

2.2 Implementation of JSON in Java
2.2.1 Basic types in JSON
JSON has several basic types. They are:
  • Number
  • String
  • Boolean
  • Array
  • Object
  • null
Notice that JSON allows several level nested. This is, the type Object could be another JSON Object, and it could contains another JSON Object inside, and so on, exactly like XML. This make JSON simple and powerful at the same time.

You can find more information about the syntax and the types here: http://en.wikipedia.org/wiki/JSON#Syntax_diagrams

2.2.2 Create a JSON Object
The basic unit of data in JSON is JSON Object, which accepts several parameters. The most useful methods to create JSON Object are
  • public JSONObject()
The empty parameter to create an empty JSON Object
  • public JSONObject (String json)
This constructor creates a JSON Object with a String which follows the rules for structures the object (see the example above). You can check Wikipedia for more information about the syntax. Basically, the objects should be enclosed between { and }, the array enclosed between [] and the values enclosed between "".
  • JSONObject(Map copyFrom)
It maps a Map, which is a set of key-values where each key is mapped to a single value. Click here for more information about Map.

2.2.3 Manipulation of single data
2.2.3.1 Introducing new values
The basic method to create a new value inside of the JSON Object is put:

put (key, value)

The key must be a String enclosed by "" and the value could be any basic type that JSON accepts, including another JSON Object. Here is the list of the methods:
  • JSONObject put (String name, int value)
  • JSONObject put (String name, long value)
  • JSONObject put (String name, Object value)
  • JSONObject put (String name, boolean value)
  • JSONObject put (String name, double value)
Be aware that when the name already exists in the JSON Object, the put method will replace the previous value. If you want to maintain the existence value/s, then the method accumulate should be used. (See section 2.2.3.5)

2.2.3.2 Obtaining a value 
The easiest way to obtain a data from JSON Object is using the method get+Data Type(String name). With these methods, the name of the value should be known in advance. Here is a list of the methods:
  • boolean getBoolean(String name)
  • double getDouble(String name)
  • int getInt(String name)
  • long getLong(String name)
  • String getString(String name)
  • JSONArray getJSONArray(name)
  • JSONObject getJSONObject(String name)
  • Object get(String name)
Notice that the JSONObject could have other JSONObject inside. In that case, several gets could be used to get the desired value.

2.2.3.3 Removing a data from JSONObject
It is easy to remove an object from JSONObject. Only the name is needed.
  • Object remove(String name)
If the value has been successfully removed, it will return the value. Otherwise, it will return null.

2.2.3.4 Converting the JSONObject to String
There are several ways to convert JSONObject to String. The easiest one is using the method toString().
  • String toString()
For example:
{"child":{"age":12,"name":"foo","type":"child"},"type":"parent"}

There is also another method similar where the indent space could be specified (The space when a child is presented) :
  • String toString (int indentSpace)
For example with indentSpace = 4:
{
    "child": {
        "age": 12,
        "name": "foo",
        "type": "child"
    },
    "type": "parent"
}

2.2.3.5 Obtain other informations:
Beside the basic methods, there are several methods that could be useful.
  • boolean has (String name)
It is used to know if the JSON Object contains o no a specific value by given the name.
  • boolean isNull(String name)
Identify if a name exists or not in the JSON Object or if it exists, the value is null or not.
  • int length()
Returns the number of the pair key-value that the JSON Object has. Notices the length doesn't include the length of the child objects that could be inside of the JSON Object. For example, if the parent object has 4 pairs of name-value, which one of them is the child JSON Object. No matter how many object that the child has, this method will always return 4.
  • JSONObject accumulate(String name, Object value)
    The accumulate method add new values into the JSON Object. Depending on the context, it could works in different way:
    1. The name doesn't exist in JSON Object: Works like the method put. It creates a new name in the JSON Object and insert the value
    2. The name exists in JSON Object as basic type (No JSONArray): It creates a JSON Array where the name is the common name and the value is a JSON Array with both values.
    3. The name exists in JSON OBject as JSON Array: It appends the new value to the JSON Array.
    • Iterator keys()
    Returns an iterator that could be used to iterate inside of the JSON object. An example of the code could be:

    JSONObject obj=new JSONObject();
    obj.put("type", "child");
    obj.put("name","foo");
    obj.put("age", new Integer(12));
    Iterator ite = obj.keys();
    while (ite.hasNext()) {
        System.out.println(ite.next());
    }

    This code prints all the names in the JSONObject: age, name, type
    • JSONArray names()
    This method returns a JSONArray of names of the JSON Object. It works exactly like the method keys(), but it returns different type of values. Here is an example of usage:
    JSONObject obj=new JSONObject();
    obj.put("type""child");
    obj.put("name","foo");
    obj.put("age"new Integer(12));

    JSONArray array = obj.names();
    for (int i = 0; i < array.length(); i++) {
        System.out.println(array.get(i));
    }

    This code will print the names in the screen: age, name, type.

    2.2.4 Using JSON Array
    The JSON Array is basically an array in Java. The main difference is it can accept any types of data that JSON has. There is not need to create a JSON array of Strings and another JSON array of Booleans save them. Instead, it could exist an unique JSON array which contains Strings and Booleans at the same time.

    2.2.4.1 Creating an JSON Array
    There are several constructors for JSON Array. The most useful are:
    • JSONArray()
    An empty constructor which creates an array with no element.
    • JSONArray(String json)
    It accepts a list of elements inside of an array enclosed by "[" and "]" and separated by "," or ";". The general recommendation is utilize always coma "," and never semicolon ";" because they performs the same task and semicolon can give some problems. For example, for an empty element (null), it could be enclosed by two comas (,,) or a left square braket and one coma ("[,"), but never two semicolons (";;"). Other problemas that it generates is when semicolon is used exactly before the semicolon (";"), there only can be a character, no left square bracket ("[") or coma is allowed (",").

    Here are some examples:

    Empty array
    String jsonArray = "[]";

    Array with one element
    String jsonArray = "[ element1 ]";

    Array with two elements
    String jsonArray = "[element1, element2]";

    Array with one normal element and one null element
    String jsonArray = "[ element1, ,]";

    Array with one normal element and two null elements
    String jsonArray  = "[element1, , ,]";

    Another interesting things is after the array is closed by the right square bracket ("]"), the string could have other characters, but they won't be parsed as value. For example:

    String jsonArray = "[element1, element2] , [element3, element4]";

    It won't give any exception, but only the first array will be recognized. 
    • JSONArray (Collection copyFrom)
    This constructor creates an JSONArray with all the elements from a collection.

    2.2.4.2 Introduction new values
    Like JSON Object, to introduce a new value utilize the method put also. In this case, there is also option to decide which part of the array the data should be (with index).

    • JSONArray put (boolean value)
    • JSONArray put (int value)
    • JSONArray put (long value)
    • JSONArray put (double value)
    • JSONArray put (String value)
    • JSONArray put (Object value)
    • JSONArray put (int index, boolean value)
    • JSONArray put (int index, int value)
    • JSONArray put (int index, long value)
    • JSONArray put (int index, double value)
    • JSONArray put (int index, String value)
    • JSONArray put (int index, Object value)

    There are several things to take account.
    1. When a method which the index is not specific is called, the value always goes to the last position.
    2. When the index is specific in the put method, it will override the previous value in that position, if any.
    3. The index cannot be negative.
    4. The index could be bigger than the original size of the array. In such case, the intermediate values will be null.
    5. Like any array in Java, the index starts from 0.
    6. Because the JSON Array and JSON Object belong to Object, they can be also put into an array.
    2.2.4.3 Obtaining a value
    To obtain a value from the array, the method get+Data Type (Int position). Make sure that the type matches, otherwise it will returns an exception.
    • boolean getBoolean (int index)
    • int getInt (int index)
    • long getLong (int index)
    • double getDouble (int index)
    • String getString (int index)
    • Object get (int index)
    • JSONArray getJSONArray (int index)
    • JSONObject getJSONObject (int index)

    Because inside of a JSONArray it could contains also JSON Array and JSON Object, several get could be called to obtain the desire value.

    2.2.4.4 Removing a data from JSON Array
    • Object remove (int index)
    This method returns the value removed or null if there is not value in the index indicated.
    Warning: Unfortunately this method only exists in Java, no in Android.

    2.2.4.5 Transforming the JSON Array to String
    Like the JSON Object, there are several ways to do it. The easiest one is using the method toString().
    • String toString()
    For example: 
    ["element1","element2","element4",4]

    There is another method which make the output easier to read for humans by adding indent spaces.
    • String toString(int indentSpaces)
    2.2.4.6 Obtain other information
    Beside the methods explained above, there are several methods that could be useful:
    • boolean isNull(int index)
    Check if the value in a specific index exists or is null or not. 
    • int length()
    Returns the length of the array.
    • boolean equals(Object o)
    Compares if two JSON arrays are equals. This is, they are the instances of the same object, not only when they have the same element.
    • String join(String separator)
    Convert all the elements of the JSON array into a String, with the separator indicated between elements.  The output is a bit different from the method toString(). Here is an example:

    String elements = "[element1, element2]";
    JSONArray array = new JSONArray(elements);
    String flatArray = array.join("+");
    System.out.println(flatArray);

    The output is:
    "element1"+"element2"

    Conclusion
    JSON is a lightweight data format with easy methods for data creation and manipulation. Although there are more complex way to interact with data, for basic operations, using JSON Object and JSON Array could be enough. Because those characteristics, JSON is the perfect notation to be used to exchange information when the data traffic matters.

    Since I am not very expert on this, there could be something that I haven't explained completely. If you have any question about it, write a comment and I will try to solve it.

    For more information:
    If the reader want to dig deeper into JSON, she can find more information about it below
    Wikipedia: http://en.wikipedia.org/wiki/JSON
    Android developer: http://developer.android.com/reference/org/json/package-summary.html
    JSON Exception: http://json.org/javadoc/org/json/JSONException.html

    No comments:

    Post a Comment