Tech Ads

Back to Article List

NOTE: BEA was acquired by Oracle, so Dev2Dev became part of OTN

Originally published February 2007 [ Publisher Link obsolete ]

An Introduction to JSON


Since BEA became part of Oracle, Dev2Dev was taken off-line and became part of Oracle's developer site OTN. In light of this, you can only find a copy of the full article here.

Abstract

Web services are practically synonymous with XML, the payload format used for communicating between client and server. However, the application architecture imposed by the appearance of Ajax and REST techniques has forced many to contemplate alternatives like JavaScript Object Notation (JSON).

JSON has come to the attention of Web service providers as a lighter and more friendly format for Web services clients in the form of a browser, or what would essentially be an Ajax enabled application taping RESTful web services.

This article will address why JSON has gained traction in Web services design, including its main benefits and constraints as an alternative to XML. It also provides an in-depth look at how to easily produce JSON output in Java Web services, accompanied by a corresponding Web service client consuming JSON.

XML crossroads : The Browser and Ajax

It'ss been a little more than a decade since the design principles of XML were first published. Since then, this markup language has taken center stage in a wide range of software application areas. Spanning configuration & deployment descriptors in mainstream platforms like Java and .NET, to more elaborate uses in application integration scenarios, the language agnostic nature of XML has given it a unique status among software architects, but even the most noted XML pundits agree that under certain circumstances the use of XML stretches the capabilities it was intended for.

One of the most recent approaches to address the viability of XML has been web enabled applications built around Ajax principles, to the extent that an alternative payload format has gained ground in favor of XML. Its name : JavaScript Object Notation (JSON). Before exploring the intricacies of this alternative markup, let's analyze were XML shows its limitations in this particular type of design.

Ajax allows web enabled applications to perform out-of-band client-server calls, establishing a separate channel on which to send and receive information from remote Web services. In layman's terms, updates and navigation sequences in Ajax applications are done outside the classical client-server context that entails a complete screen refresh, with the information being received in the background (a.k.a out-of-band). See An Introduction to Ajax by David Teare (Dev2Dev) for more background.

These application updates that are typically obtained from RESTful Web services, once received in a user's browser need to be incorporated in the overall HTML page layout, which is exactly were XML proves to be more than a handful. Though the capabilities of most mainstream browsers have increased over the years with the support of scripting languages and plug-in support, many programming tasks still remain difficult or unnatural to perform, one of them being manipulating and processing text.

With HTML markup being similar to XML, we can use this as our benchmark in our ease of use test. In a typical scenario, the simplest form of modifying the markup on a web page is making a new request to a server-side application for obtaining a new layout; if this is not possible, then you are left with the choice of using the Document Object Model (DOM). Since Ajax principles are precisely bound to avoiding a classical server-side request, our only option for incorporating Ajax data requests is also via DOM.

The complexity in using DOM lies in its function based roots, with a simple modification or access to a data tree requiring numerous method calls. Not to mention DOM is known for differing implementation details among various browsers, this process takes us to a very elaborate programming scheme with ample possibilities for a breakdown in cross-browser compatibility. So the outstanding question now becomes : How can a markup language be easily integrated into an HTML layout page to accommodate Ajax requirements?

The answer comes in the form of leveraging a common component in all mainstream browsers : The JavaScript engine. Instead of delivering Ajax updates in a format such as XML, which would require the use of a mechanism like DOM to access and incorporate data into a layout, a more natural and intuitive approach would be using a format that fits natively to the aforementioned engine, namely JSON.

Now that we have addressed the place JSON has with respect to XML and Ajax applications, let's take a closer look at the technical details behind JSON.

JSON under the hood : Benefits and constraints

The first thing you should realize about JSON is that it remains a simple text format—just like XML—which is relatively easy to read and inspect with the naked eye. At a syntax level, what starts to set JSON apart from other formats is the characters used to separate data, which are mainly constrained to apostrophes ', brackets ( ), [ ], { }, colons : and commas ,. The following listing illustrates what a JSON payload looks like.

{"addressbook": {"name": "Mary Lebow",
    "address": {
        "street": "5 Main Street"
        "city": "San Diego, CA",
        "zip": 91912,
    },
    "phoneNumbers": [
        "619 332-3452",
        "664 223-4667"
    ]
 }
}

Benefits

Making use of the aforementioned data separators might not be too obvious at first glance, but there is a fundamental reason behind them: easier data access. As it turns out, the internal representation used by JavaScript engines for data structures like strings, arrays and objects, are precisely these same characters.

Where this leads us is to a more straightforward approach for accessing data than the alternate DOM technique, but lets take a look at a few JavaScript code snippets to illustrate this process. These snippets access the information in the previous JSON snippet:

  • Name access from JSON : addressbook.name
  • Street address access from JSON : addressbook.address.street
  • First phone number access from JSON : addressbook.address.phoneNumbers[0]

If you have done some type of DOM programming you will probably notice the contrast immediately, but just in case you haven't, here is an external resource to the Document Object Model which contains a small example for navigating across data.

Another added benefit of JSON is its less verbose nature. In XML, the opening and closing of tags is a necessity just for markup compliance, but in JSON's case all that's required is a simple bracket for closure. In data exchanges comprising a hundred or more fields, this additional XML markup can add to transit times. There is no formal study concluding that JSON is more efficient than XML over the wire; it's simply a matter of byte to byte comparison, where an equivalent JSON and XML payload is always smaller in the former than in the latter format. How much of a difference this makes, especially in the light of the new XML compression formats, remains to be seen.

Constraints

Like many benefits, JSON's less verbose format can cut both ways and in this sense lacks a few of XML's properties. Namespaces, which allow the mixing of identical pieces of information in different contexts is clearly missing in JSON. Still another differing feature is that of attributes, since every JSON assignment is done with colons :, when transforming XML to JSON it can be difficult to distinguish between what would be considered text between tags—XML CDATA—or the actual value of attributes.

You may also find the actual creation and validation of JSON a little more complex than an average XML fragment. In this sense, it may be that XML has had a head start in terms of developing tools for its processing, but you will soon realize the number of utilities for JSON pales in comparison to those for XML. Nevertheless, and to ease any worries you may have in this aspect, we will be exploring some of the most mature JSON developments in our next section : Producing JSON output.

Producing JSON output with Web services

Since the primary target for JSON are out-of-band request's from browsers, our choice for producing this data will be a RESTful Web service. Besides the typical business logic that would go behind the Web service, we will be using a special API designed to convert native Java structures into a JSON format (see reference section for details ). To start things off, here's the Java code to manipulate Address objects:

// Create addressbook data structure
SortedMap addressBook = new TreeMap();

// Create new address entries and place in Map 
// (See download for Address POJO structure)
Address maryLebow = new Address("5 Main Street","San Diego, CA",91912,"619-332-3452","664-223-4667"); 
addressBook.put("Mary Lebow",maryLebow);

Address amySmith = new Address("25 H Street","Los Angeles, CA",95212,"660-332-3452","541-223-4667"); 
addressBook.put("Sally May",amySmith);

Address johnKim = new Address("2343 Sugarland Drive","Houston, TX",55212,"554-332-3412","461-223-4667"); 
addressBook.put("John Kim",johnKim);

Address richardThorn = new Address("14 68th Street","New York, NY",                                  ,12452,"212-132-6182","161-923-4001"); 
addressBook.put("Richard Thorn",richardThorn);

The place in which this Java structure is generated is irrelevant to our case—it could be in a JSP, Servlet, EJB or POJO—the only thing that will concern us is having access to such data inside the RESTful Web service, which is shown in this next listing:


// Define placeholder for JSON response
String result = new String();

// Get parameter (if any) passed into application 
String from = request.getParameter("from");
String to = request.getParameter("to");

try { 
    // Check for parameters, if passed filter address book 
    if(from != null && to != null) { 
      // Filter address book by initial 
      addressBook = addressBook.subMap(from,to);
    } 

   // Prepare the convert addressBook Map to JSON array 
   // Array used to place numerous address entries 
   JSONArray jsonAddressBook = new JSONArray();
 
   // Iterate over filtered addressBook entries 
   for (Iterator iter = addressBook.entrySet().iterator(); iter.hasNext();)  { 

     // Get entry for current iteration        
     Map.Entry entry = (Map.Entry)iter.next();
     String key = (String)entry.getKey();
     Address addressValue = (Address)entry.getValue();

     // Place entry with key value assigned to "name" 
     JSONObject jsonResult = new JSONObject();
     jsonResult.put("name",key);

     // Get and create address structure corresponding to each key 
     // appending address entry in JSON format to result 
     String streetText = addressValue.getStreet();
     String cityText = addressValue.getCity();
     int zipText = addressValue.getZip();
     JSONObject jsonAddress = new JSONObject();
     jsonAddress.append("street",streetText);
     jsonAddress.append("city",cityText);
     jsonAddress.append("zip",zipText);
     jsonResult.put("address",jsonAddress);

     // Get and create telephone structure corresponding to each key 
     // appending telephone entries in JSON format to result 
     String telText = addressValue.getTel();
     String telTwoText = addressValue.getTelTwo();
     JSONArray jsonTelephones = new JSONArray();
     jsonTelephones.put(telText);
     jsonTelephones.put(telTwoText);
     jsonResult.put("phoneNumbers",jsonTelephones);


     // Place JSON address entry in global jsonAddressBook 
     jsonAddressBook.put(jsonResult);
   } // end loop over address book 

     // Assign JSON address book to result String  
     result = new JSONObject().put("addressbook",jsonAddressBook).toString();

  } catch (Exception e) { 
     // Error occurred      
  }

For ease of illustration, we've simply put this code into a JSP (restservice.jsp). If this was a real application, code like this would probably be found in a servlet or helper class. This RESTful Web service initially extracts two input parameters passed to it via the URL request, and based on these values, filters our existing address book to fit requirements. Once the address book is filtered, we start an iteration inspecting every entry in the Java Map.

You will notice that inside the loop, we make extensive use of the json.org API to transform our native Java format into a JSON string. Though we only make use of a few classes namely JSONArray and JSONObject, the transformation methods provided by this API are extensive, with capabilities for even transforming XML structures into JSON output. But getting back to our Web service, once we finish looping over every entry, the variable result will contain the JSON equivalent of our address book ready to be returned to the requesting party.

Now that we have generated JSON output, let's take a look at the other half : Consuming JSON payloads in browser applications.

Consuming JSON payloads

Being a browser based client, the bulk of our design will be done in HTML & JavaScript, accompanied by an additional JavaScript framework. In our example we use the Prototype library to easily create Ajax calls in a cross-browser fashion. This next listing contains the first part of our application along with its corresponding JavaScript functions :

<html> 
<head> 
<title> JSON Address Book </title> 
<script type="text/javascript" src="prototype-1.4.0.js"></script> 
<script type="text/javascript"> 
// Method invoked when user changes letter range
function searchAddressBook()	{

  // Select values from HTML select lists
  var fromLetter = $F('fromLetter');
  var toLetter = = $F('toLetter');

  // Prepare parameters to send into REST web service
  var pars = 'from=' + fromLetter + '&to=' + toLetter;
  // Define REST web service URL 
  var url = 'restservice.jsp';

  // Make web service Ajax request via prototype helper, 
  // upon response, call showResponse method		
  new Ajax.Request( url, { method: 'get', parameters: pars, 
                           onComplete: showResponse });
}

</script> 
</head>

At the top you will notice we import the prototype library used to facilitate Ajax calls to our RESTful Web service. Next, you will see the searchAddressBook() function that is triggered when a user modifies an HTML selection list, shown below. When this last step occurs, the following takes place: We obtain the options selected from the HTML lists and place them inside two variables that will be used to filter our address book, later defining an additional variable pointing to our RESTful service URL restservice.jsp.

Still inside this method is the actual Ajax Web service invocation with the help of the prototype function new Ajax.Request( url, { method: 'get', parameters: pars, onComplete: showResponse });, indicating a call to the url in question, with the parameters contained in pars and the final execution of showResponse() once the Ajax call is terminated.

A look at the method showResponse() illustrates the necessary code to evaluate the JSON payload and place it in the context of the HTML body layout:

// Method invoked when page receives Ajax response from REST web service 
function showResponse(originalRequest)	{
   // Get JSON values 
   jsonRaw = originalRequest.responseText;
   // Eval JSON response into variable 
   jsonContent = eval("(" + jsonRaw + ")");

   // Create place holder for final response    
   finalResponse = "<b>" + jsonContent.addressbook.length + 
                   " matches found in range</b><br/>";

   // Loop over address book length.
   for (i = 0; i < jsonContent.addressbook.length; i++) {
        finalResponse += "<hr/>";
        finalResponse += "<i>Name:</i> " + jsonContent.addressbook[i].name + "<br/>";          
        finalResponse += "<i>Address:</i> " + jsonContent.addressbook[i].address.street + " -- " + 
                          jsonContent.addressbook[i].address.city + "," +           
                          jsonContent.addressbook[i].address.zip + ".<br/>";          
        finalResponse += "<i>Telephone numbers:</i> " + jsonContent.addressbook[i].phoneNumbers[0] + " & " + 
        jsonContent.addressbook[i].phoneNumbers[1] + ".";          
   }

   // Place formatted finalResponse in div element
   document.getElementById("addressBookResults").innerHTML = finalResponse;
 }

The input parameter for this method is whatever response our RESTful Web Service returned upon invocation. As you can see, since we know beforehand we will be dealing with a JSON string, we take the input and make use of the JavaScript eval() function in order to place it in memory and allow data access. It's this simplicity that drives developers to use JSON. No parsing is needed at all. A simple eval() results in JavaScript structures that we can manipulate just like any other JavaScript structures.

Once the JSON response is eval'd, we create a JavaScript loop to extract every address entry and place each match inside a containment variable named finalResponse, which in itself will include all the necessary formatting to display the final address book in the page layout, with placement being done at the end of the loop via document.getElementById("addressBookResults").innerHTML.

Finally and just for completeness, the actual layout of our page is composed of the following code :

<body> 
<h4 style="text-align:left">Request address book matches:</h4>
<table style="text-align:left" cellpadding="15"><tr><td valign="top">From:<br/>
<select id="fromLetter" size="15" onchange="searchAddressBook()">
	<option>A</option>
	...
	<option>Z</option>
</select>
</td><td valign="top">To:<br/>
<select id="toLetter" size="15" onchange="searchAddressBook()">
	<option>A</option>
	...
	<option>Z</option>
</select>
</td><td valign="top">
<h5> Results </h5> 
<div style="text-align:left" id="addressBookResults">Please select range</div>
</td></tr>
</table>
</body> 

The biggest thing worth mentioning about the previous listing is the HTML selection lists, which upon modification triggers the JavaScript method needed to invoke the out-of band Ajax call, and of a lesser importance, the <div> element which is where the formatted JSON response is placed.

With this we conclude our look at consuming JSON payloads and the overall picture regarding the use of JSON as alternate format to XML in Web Services and Ajax applications.

-->

Example Code

You can download the code associated with this article.

To install, ....

Summary

Though the X in Ajax stands for XML and Web services have come to the forefront by the steady use of this same format, it doesn't necessarily mean such an approach is cast in stone. As we have seen, XML has a few drawbacks when applied to Ajax enabled applications due to the text processing capabilities in browsers, and in this sense, JSON has emerged to provide a compelling alternative in this same context.

Having reviewed both the benefits and drawbacks of JSON's syntax, along with a comprehensive look at how to create JSON output from RESTful Web services and how to consume such data into a web page layout, you should now be in an ideal position to not only offer your end users JSON enabled Web services, but also tap the wide range of Web services currently offered which make use of this up and coming format.

References

  • The article An Introduction to Ajax by David Teare (Dev2Dev) provides a good background to Ajax
  • JSON in Java - Java API used for transforming native Java structures in JSON output.
  • Prototype - JavaScript framework for creating Ajax enabled applications.

Originally published February 2007 [ Publisher Link obsolete ]

NOTE: BEA was acquired by Oracle, so Dev2Dev became part of OTN

Back to Article List