An Introduction to JSON

by Daniel Rubio
02/28/2007

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 accessing RESTful Web services.

This article addresses 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's 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. From configuration and 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 where 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, which 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 where 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, which is typically done using 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. In addition, 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 ,. This 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"

    ]

 }

}

To place this last JSON example in context, this listing shows the equivalent payload written in XML:

<addressbook>

 <name>Mary Lebow</name>

 <address> 

    <street>5 Main Street</street>

    <city zip="91912"> San Diego, CA </city>

    <phoneNumbers>

      <phone>619 332-3452</phone>

      <phone>664 223-4667</phone>

    </phoneNumbers>

 </address>

</addressbook>

Similar, right? But definitely not identical, so let's elaborate on the benefits and constraints of using JSON's syntax.

Benefits

Making use of JSON's data separators may 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 let's 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.

An 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.

Additionally, JSON has garnered the attention of many developers specializing in different programming languages, giving way to libraries capable of producing this format from environments as diverse as Haskell and Lisp to more mainstream options like C# and PHP ( see the References section for details ).

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. 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—and 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. Nevertheless, and to ease any worries you may have in this area, we will be exploring some of the most mature JSON developments in our next section.

Producing JSON Output with Web Services

Since the primary target for JSON is out-of-band requests 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 the References 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, a servlet, an 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 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 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 in a 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 make use of only 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 of the equation: consuming JSON payloads in browser applications.

Consuming JSON Payloads

Being a browser-based client, the bulk of our design will be done in HTML and 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 this 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.

Is JSON for You ?

Like all design choices in software, your requirements will provide the answer to this question. If your Web services consumers will be created in a classical, full-fledged programming environment—Java , .NET , PHP, or Ruby, to name a few—then you can probably make due without JSON. Given the open-ended capabilities of most programming language environments, providing you total configuration control not to mention access to custom libraries, parsers, or helper classes, the difference between consuming JSON, XML, or any other type of Web services payload should be negligible.

If on the other hand, your Web services consumers will be confined to the environment of a browser, JSON deserves serious consideration. Consuming Web services in a browser is not done for the sheer fun of it but rather as a real business requirement. If your manager comes to you and requires one of those "slick Web 2.0 interfaces" that appear to load data without a delay/refresh, then you would be entering the technical realm of Ajax and Web services consumption in browsers.

In these last circumstances, you would not only be limited to the processing environment of a machine located across a network, but one under tight control of a random user, limiting even the most resourceful developer to work with a lowest common denominator for processing text in browsers: the DOM, which as outlined earlier, is a difficult undertaking when compared to accessing a JSON tree.

Example code

You can download the code associated with this article.

To install, unzip the downloaded file and place addressbook.html, prototype-1.4.0.js, and restservice.jsp under your preferred application directory. Copy the included json.jar library into the /WEB-INF/lib directory of this same application. Visit <yourhost>/>yourappdir>/addressbook.html and make selections from the HTML lists. That's it. You're up and running with JSON!

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. 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 to tap the wide range of Web services currently offered that make use of this up and coming format.

References

  • JSON in Java - Java API used for transforming native Java structures in JSON output
  • Prototype - JavaScript framework for creating Ajax-enabled applications
  • JSON.org - JSON home page, which includes additional resources and links to various language libraries capable of producing JSON

Daniel Rubio is a software consultant with over 10 years of experience in enterprise software development, having recently founded Mashup Soft, a startup specializing in the use Web services for Mashups.