Site Sponsors:
Parsing JSON using GSON 
IMHO, Google is fast emerging as the coolest mecca for plus-one innovations. -From Android (+1 on Java / Blackberry) to GWT (+1 on CORBA / XDR), there is simply no better place to watch savvy engineers "embrace and extend" several time-proven ideas.

Such is the case with Google's GSON for Java-Script Object Notation (JSON) (a +1 on json.org): Designed to be a better way to move data in and out of our projects (also known as "serialization"), Google's effort to one-up the ante around the "Fame, Fortune, or Fun" table should get our propellers spinning.



For example, SourceForge.net (also +1'ed by Google eventually hosting their OWN open software developer site) offers an excellent way to query their hosts for the stats on a project.


{
"oses": [["Windows", 29], ["Unknown", 5], ["Linux", 4], ["Macintosh", 2]],
"end_date": "2012-01-20 00:00:00",
"countries": [["United States", 16], ["Italy", 8], ["Ghana", 3], ["Romania", 3], ["United Kingdom", 3], ["Germany", 3], ["Egypt", 1], ["Israel", 1], ["France", 1], ["Hong Kong", 1]],
"downloads": [["2012-01-05 00:00:00", 4], ["2012-01-06 00:00:00", 4], ["2012-01-07 00:00:00", 0], ["2012-01-08 00:00:00", 0], ["2012-01-09 00:00:00", 0], ["2012-01-10 00:00:00", 0], ["2012-01-11 00:00:00", 0], ["2012-01-12 00:00:00", 0], ["2012-01-13 00:00:00", 1], ["2012-01-14 00:00:00", 1], ["2012-01-15 00:00:00", 0], ["2012-01-16 00:00:00", 6], ["2012-01-17 00:00:00", 15], ["2012-01-18 00:00:00", 6], ["2012-01-19 00:00:00", 0], ["2012-01-20 00:00:00", 3]],
"messages": ["Download statistics available since 2012-01-05 (when this project was registered)."],
"period": "daily",
"start_date": "2012-01-05 00:00:00",
"total": 40,
"stats_updated": "2012-01-26 09:01:09",
"summaries": {
"os": {
"top": "Windows",
"percent": 72,
"modifier_text": ""
},
"geo": {
"top": "United States",
"percent": 40,
"modifier_text": ""
},
"time": {
"downloads": 40
}
}
}


Detectable by JSON, we recently decided to use GSON to play with the results:


import com.google.gson.Gson;

public class Test {

public static void main(String... args) throws Exception {
String json =
"{\"oses\": [[\"Windows\", 29], [\"Unknown\", 5], [\"Linux\", 4], [\"Macintosh\", 2]], \"end_date\": \"2012-01-20 00:00:00\", \"countries\": [[\"United States\", 16], [\"Italy\", 8], [\"Ghana\", 3], [\"Romania\", 3], [\"United Kingdom\", 3], [\"Germany\", 3], [\"Egypt\", 1], [\"Israel\", 1], [\"France\", 1], [\"Hong Kong\", 1]], \"downloads\": [[\"2012-01-05 00:00:00\", 4], [\"2012-01-06 00:00:00\", 4], [\"2012-01-07 00:00:00\", 0], [\"2012-01-08 00:00:00\", 0], [\"2012-01-09 00:00:00\", 0], [\"2012-01-10 00:00:00\", 0], [\"2012-01-11 00:00:00\", 0], [\"2012-01-12 00:00:00\", 0], [\"2012-01-13 00:00:00\", 1], [\"2012-01-14 00:00:00\", 1], [\"2012-01-15 00:00:00\", 0], [\"2012-01-16 00:00:00\", 6], [\"2012-01-17 00:00:00\", 15], [\"2012-01-18 00:00:00\", 6], [\"2012-01-19 00:00:00\", 0], [\"2012-01-20 00:00:00\", 3]], \"messages\": [\"Download statistics available since 2012-01-05 (when this project was registered).\"], \"period\": \"daily\", \"start_date\": \"2012-01-05 00:00:00\", \"total\": 40, \"stats_updated\": \"2012-01-26 09:01:09\", \"summaries\": {\"os\": {\"top\": \"Windows\", \"percent\": 72, \"modifier_text\": \"\"}, \"geo\": {\"top\": \"United States\", \"percent\": 40, \"modifier_text\": \"\"}, \"time\": {\"downloads\": 40}}}";

// Wow - This was easy!
SourceForgeData01 data = new Gson().fromJson(json, SourceForgeData01.class);

// The data conversion:
System.out.println(data.toTDF());
}
}


Here are the supporting classes:


import com.google.gson.annotations.SerializedName;

/**
*
* @author profnagy
*/
class SourceForgeData01 {

@SerializedName("stats_updated")
public String statsUpdated = "";
@SerializedName("start_date")
public String startDate = "";
@SerializedName("end_date")
public String endDate = "";
@SerializedName("total")
public String totalDownload = "";
@SerializedName("summaries")
public DataDownloadSummary downloadArray = new DataDownloadSummary();

public String toTDF() {
StringBuilder sb = new StringBuilder();
sb.append(this.totalDownload);
sb.append("\t");
sb.append(this.startDate);
sb.append("\t");
sb.append(this.endDate);
sb.append("\t");
sb.append(this.statsUpdated);

sb.append("\t");
sb.append(this.downloadArray.os.top);
sb.append("\t");
sb.append(this.downloadArray.os.percent);
sb.append("%\t");
sb.append(this.downloadArray.geo.top);
sb.append("\t");
sb.append(this.downloadArray.geo.percent);
sb.append("%");
return sb.toString();
}
}


~ then, given the structure of "summaries" ~


/**
*
* @author profnagy
*/
class DataDownloadSummary {
public TopPercent os = new TopPercent();
public TopPercent geo = new TopPercent();
}


~ and finally ~


import com.google.gson.annotations.SerializedName;

/**
*
* @author profnagy
*/
public class TopPercent {
@SerializedName("top")
public String top = "";
@SerializedName("percent")
public int percent = -1;
}


Here is the result:


run:
40 2012-01-05 00:00:00 2012-01-20 00:00:00 2012-01-26 09:01:09 Windows 72% United States 40%
BUILD SUCCESSFUL (total time: 1 second)


While massively easy to parse tagged values & arrays, we have yet to discover a way to parse those untagged / anonymous record arrays (such as "downloads" in the above) without resorting to pre-processing. Never the less, when it comes time to parse classic JSON tagged values, GSON results are proving to be almost worthy of a "+2".

Enjoy,

-Rn



Comments

Add Comment
Comments are not available for this entry.