Peter has posted 2 posts at DZone. View Full User Profile

Effective JSON with Google Web Toolkit

07.23.2010
| 11085 views |
  • submit to reddit
Hopefully every developer knows JSON protocol or has at least heard about it. In Google Web Toolkit technology, JSON is a very common protocol because:
  • JSON protocol is very simple to use,
  • JSON protocol is not wrapped into XML format and JSON payload does not contain any tag mess or overhead,
  • JSON protocol can be easily used in mobile devices without leading to heavy weight code,
  • and last but not least: many of third-party services offers REST-like services with JSON responses.

It does not matter which point is the most important for you, but the current mainstream reason is to reuse free web services and integrate them into your applications in order to provide maximum functionality in minimal development time. So the question is why to reinvent the wheel again and again if there exists:

  • a free online video sharing server with almost unlimited resources - YouTube,
  • a free online photo sharing server with rich functionality - Flickr,
  • an online financial news server - Yahoo! Finance, social networks - Facebook, Yahoo! Social Directory, Google OpenSocial, ... somewhere in the online universe.

Facebook logoYoutube logoFlickr logoGoogle OpenSocial

Online services running in the cloud offer tremendous possibilities to us, as they can handle a large amount of data for millions of users simultaneously. You will probably never reach the scalability and performance that Google have achieved with their YouTube services. So the question is not why to use all these free services,  but how to use them in the most efficient way? We are going to be focused on the Google Web Toolkit framework as a pure AJAX Web 2.0 solution which can be deployed on Google App Engine.

Acris JSONizer is the answer! ... but what was the question?

Let's start with the example step by step. We choose Facebook, the most popular social network, and will use their REST like web services in order to integrate Facebook data with your GWT application.

Requesting the data from Facebook service

Facebook graphThe Facebook Graph API allows to developers read and write data to Facebook and presents a simple, consistent view of the Facebook social graph, uniformly representing objects in the graph (e.g., people, photos, events, and fan pages) and the connections between them (e.g., friend relationships, shared content, and photo tags). This complex social infrastructure can be fetched from https://graph.facebook.com/ID URL where ID represents an unique ID of every object in the social graph (for example Coca-Cola company has id cocacola so the request URL should be https://graph.facebook.com/cocacola).

Let's see an example of how to request Facebook data and use it in an application built on top of the Google Web Toolkit framework. This approach was perfectly described by Chris Fong in his great article http://www.gwtsite.com/how-to-access-web-services-with-gwt/ and was used many times in real projects such as gwt-youtube-api or synapso (The full Java source of the demo can be found as a part of acris showcase).

public class ShowFacebookData implements EntryPoint {

private static final String FACEBOOK_URL = "https://graph.facebook.com/google";

@Override
public void onModuleLoad() {

new FacebookRequest().doRequest(FACEBOOK_URL, new AsyncCallback<JSONObject>() {

@Override
public void onSuccess(JSONObject arg0) {
parseData(arg0);
}

@Override
public void onFailure(Throwable arg0) {
GWT.log("Unable to obtain data from facebook", arg0);
Window.alert("Unable to obtain data from facebook (reason: " + arg0.toString() + ")");
}
});
}

public void showCompany(Company company) {
RootPanel.get().add(new CompanyPage(company));
}
}

JSON data deserialization

How to parse the response data from Facebook rest-like web service in JSON format is the most important part:

{
"id": "104958162837",
"name": "Google",
"picture": "http://profile.ak.fbcdn.net/object3/812/32/s104958162837_4089.jpg",
"link": "http://www.facebook.com/Google",
"category": "Websites",
"username": "Google",
"founded": "1998",
"company_overview": "Google is a public and profitable company focused on search services. Named for the mathematical term \"googol,\" Google operates web sites at many international domains, with the most trafficked being www.google.com. Google is widely recognized as the \"world's best search engine\" because it is fast, accurate and easy to use. The company also serves corporate clients, including advertisers, content publishers and site managers with cost-effective advertising and a wide range of revenue generating search services. Google's breakthrough technology and continued innovation serve the company's mission of \"organizing the world's information and making it universally accessible and useful.\"",
"mission": "Google's mission is to organize the world's information and make it universally accessible and useful.",
"products": "See a full list:\nhttp://www.google.com/options/index.html",
"fan_count": 1633056
}

This JSON structure is pretty easy and is used mainly for presentation purposes. This should be mapped into following data structure:

public class Company {

private String id;

private String name;

private String picture;

private String link;

private String category;

private String username;

private String founded;

private String overview;

private String mission;

private String products;

private Integer fan_count;

... getters & setters in a standard java bean manner
}

Now in three steps you can achieve JSON data mapping a simple way using the acris-json project:

  • Annotate data structure with @JSONObject annotation
  • Annotate each class field which should be mapped into JSON data with @Field annotation
  • Start deserialization process using this code:
JsonizerBuilder jsonizerBuilder = new JsonizerBuilder();
IJsonizer jsonnizer = jsonizerBuilder.create();
Company company = jsonnizer.fromJson(arg0, Company.class);

The result Company class with the correct annotations should looks like this:

public class Company {

@Field
private String id;

@Field
private String name;

@Field
private String picture;

@Field
private String link;

@Field
private String category;

@Field
private String username;

@Field
private String founded;

@Field(value="company_overview")
private String overview;

@Field
private String mission;

@Field
private String products;

@Field
private Integer fan_count;

... getters & setters in a standard java bean manner
}

Now, let's see a result:

 

Result

 

The deserialized result can displayed in whatever form you want, for example like in the picture above.

You can find the full demo on acris pages or you can try the deployed application on Google App Engine. (keep in mind there are no iframes in order to display facebook data, only JSON data from the REST services and GWT code)

So the answer to ultimate question of developers Life, the Internet and Everything is Acris!

Legacy
Article Resources: 
Published at DZone with permission of its author, Peter Simun.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Harald Pehl replied on Mon, 2010/07/26 - 3:26am

There's an alternative JSON mapper available called Piriti. Using Piriti you can map fairly complex JSON and/or XML data to arbitrary POJOs and GXT models. All mapping information is provided using annotations. Piriti supports many different data types and collections and is able to handle inheritance and references in your POJOs.

Feel free to take a look at it under: http://code.google.com/p/piriti.

Peter Simun replied on Fri, 2010/07/30 - 1:14pm in response to: Harald Pehl

Hi Harald,

Is it possible to somehow merge the results in one monolitic solution? Wouldn't it be better to have only one more stable framework?

Peter

Harald Pehl replied on Thu, 2010/08/05 - 7:14am in response to: Peter Simun

Hi Peter,

the idea of one more stable framework sounds good to me! As I see it the JSON mapping you describe in the article is part of the "acris" framework. Are you developing the framework or the JSON part of it? How is the JSON mapping implemented in acris? Do you use deferred binding?

Piriti does heavily use deferred binding. It also offers XML mapping. I have a list of planned features. Maybe arcis already implements some points of it.

I look forward to hearing from you.
- Harald

Peter Simun replied on Sat, 2010/08/07 - 12:10pm in response to: Harald Pehl

Hello Harald,
just read your response to my article http://java.dzone.com/articles/efective-json-google-web.
That is great that you thinking in a same way - imho it's better to join the effort instead reinventing the wheel.

To answer your question:
Yes, I'm the lead developer of the acris and also the acris-json. Acris-json strongly uses deffered binding. For example gwt-youtube-api is completely built on top of acris-json (http://code.google.com/p/gwt-youtube-api/)

I really like pirity because it provides whole set of functionality in a consistent way. In acris we were mostly focused only for JSON, because XML is very inefficient - from the transfered data overhead point of view.

Are you using pirity in some production system?
Do you have some performance tests? So we can measure the results?

Do you have some idea how we can proceed with joining these solutions into one result?

Thank you,
Peter

Harald Pehl replied on Mon, 2010/08/09 - 5:24am in response to: Peter Simun

Hi Peter, to simplify things I started a little brainstorming on Google Docs. If you sent me your email, I will share the relevant folder / document. - Harald harald.pehl@googlemail.com

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.