Introduction and sample data
JSON is currently one of the more widely used formats for data exchange between various languages and services. While developing for Android, you will often come across situations where you would be required to parse JSON responses from servers. We will use the following example available at the JSON site.
[sourcecode language="java"]
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}
[/sourcecode]
The JSON data shown above has numerous nested objects, name-value pairs and also an array.
Data Analysis
Just a low down on JSON before we begin implementing the parser. JSON is basically a collection of nested name-value pairs where the names are strings and the values could be strings, integers, doubles, objects, etc. (Of course, represented in a string format). Analyzing our sample data will give us a clearer idea.
Each object is encapsulated in {…}. So here the outermost set of {…} defines the root object. Inside are defined nested objects such as glossary, GlossDiv, GlossList, GlossEntry, etc. The objects also include name-value pairs. If you look at the GlossEntry object, the member variables are ID, SortAs, GlossTerm, etc. In our example, these are all string values, but these could have been any of the basic data types such as integer, real, etc.
Now observe the object GlossDef, you will see that it contains a JSON array which is denoted by [...]. JSON can contain array of the normal data types and also objects. In our case we have an array of strings, with the value GML, XML.
JSON and Android
You can use either the JSONObject found in the org.json library or the JSONReader found in android.util. In the following tutorial we will be learning how to use JSONObject to parse our JSON data. This is because, the JSONObject has been a part of android since API level 1 while JSONReader has been added more recently, since API Level 11. So if you plan to support your application for older Android versions, be careful with your choice of implementation.
JSON Parser
Here is the code for the JSON Parser which parses the sample data provided above and displays it in a TextView.
[sourcecode language="java"]
private boolean parse(String strJson){
if( strJson.contentEquals("") ){
return false;
}
try {
//Main object
JSONObject mainObj = new JSONObject(strJson);
Log.i(TAG, "Main OBJ : " + mainObj.length() + " items.");
output += "MAIN OBJ ["+mainObj.length()+"]\n";
//Glossary object
JSONObject glossaryObj = mainObj.getJSONObject("glossary");
Log.i(TAG, "Glossary OBJ : " + glossaryObj.length() + " items.");
output += "\tGLOSSARY OBJ ["+glossaryObj.length()+"]\n";
String glossTitle = glossaryObj.getString("title");
output += "\t\tTitle : "+glossTitle+"\n";
//GlossDiv Object
JSONObject glossDivObj = glossaryObj.getJSONObject("GlossDiv");
output += "\t\tGLOSS DIV OBJ ["+glossDivObj.length()+"]\n";
String glossDivTitle = glossDivObj.getString("title");
output += "\t\t\tTitle : "+glossDivTitle+"\n";
//GlossList object
JSONObject glossListObj = glossDivObj.getJSONObject("GlossList");
output += "\t\t\tGLOSS LIST OBJ ["+glossListObj.length()+"]\n";
//GlossEntry object
JSONObject glossEntryObj = glossListObj.getJSONObject("GlossEntry");
output += "\t\t\t\tGLOSS ENTRY OBJ ["+glossEntryObj.length()+"]\n";
//Read the fields of GlossEntity
HashMap<String, String> glossEntryInfo = new HashMap<String, String>();
glossEntryInfo.put("ID", glossEntryObj.getString("ID"));
glossEntryInfo.put("SortAs", glossEntryObj.getString("SortAs"));
glossEntryInfo.put("GlossTerm", glossEntryObj.getString("GlossTerm"));
glossEntryInfo.put("Acronym", glossEntryObj.getString("Acronym"));
glossEntryInfo.put("Abbrev", glossEntryObj.getString("Abbrev"));
glossEntryInfo.put("GlossSee", glossEntryObj.getString("GlossSee"));
for( Entry<String,String> entry : glossEntryInfo.entrySet() ){
output += "\t\t\t\t\t"+entry.getKey()+" : "+entry.getValue()+"\n";
}
//Read the GlossDef object
JSONObject glossDefObj = glossEntryObj.getJSONObject("GlossDef");
output += "\t\t\t\t\tGLOSS DEF OBJ ["+glossDefObj.length()+"]\n";
String glossDefPara = glossDefObj.getString("para");
output += "\t\t\t\t\t\tpara : "+glossDefPara+"\n";
//Read the JSON Array
JSONArray glossSeeAlsoArray = glossDefObj.getJSONArray("GlossSeeAlso");
output += "\t\t\t\t\t\tGlossSeeAlso : "+glossSeeAlsoArray.length()+" entries\n";
for(int i = 0; i < glossSeeAlsoArray.length(); i++ ){
output += "\t\t\t\t\t\t\t\t"+glossSeeAlsoArray.getString(i)+"\n";
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
return true;
}
[/sourcecode]
Explanation and suggestions
Create the root object as a JSONObject. It’s constructor takes a string as input. We call the getType(String name) where the Type could be either a JSONObject, a JSONArray or a basic data type. These methods return data if the value is of Type or if the value can be converted to the requested Type.
There is another method of the form optType(String name, Type optional), where the variable is optional. The user can specify a default value which is returned if the field is missing.
In our example, we use the getString() extensively as most of the fields are string fields. In the GlossDef object, one of the fields [GlossSeeAlso] is of the array type. We have used the getJSONArray() method to obtain it.
The length() method returns the size of the array in case of JSONArray and the number of member variables in case of the JSONObject.
The Final review
We learnt,
- basics of JSON
- how to write a JSON parser using the JSONObject.
You can find the code here.
Very helpful. I am using a similar approach for parsing a JSON response from a server on my laptop in an application on an Android phone.
Adding the lines for TAG, output and corresponding import statements would have made this more complete.
Thank you for this tutorial.
I actually couldn’t finish the complete tutorial as this was a part of a series and the data source became paid from free
I wanted to put up the complete working code once I was done.