ACET




REST tutorial

Developing a client

We will now develop a JavaScript-based client to go with our auction service. Since our service can’t do much beyond retrieve items yet, that’s what we’ll make our client do.

In $CATALINA_HOME/webapps, create another directory, called auclient. In this directory, create a file auclient.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Auction site</title>

<script language='javascript'>
</script>

</head>
<body>
<h1>List items</h1>

<!-- When the user clicks on this button, call the JavaScript
     view_all_items() function -->
<button onclick='view_all_items();'>View all items</button>

<div id='itemlist'></div>

</body>
</html>

This is the only static HTML we will need for this part of the client. Everything else is generated dynamically, using AJAX-style calls in JavaScript. AJAX stands for Asynchronous JavaScript And XML, and is a browser-based technique for refreshing or changing web pages with new data without requesting the entire page again. It is the technology which underpins the user interface in Google Maps, for example.

Getting started with AJAX

With AJAX, we make an asynchronous request to the server for the list of all items in the auction, using the XMLHttpRequest object. At some point in the future, the server’s reply to our request comes back, and we are alerted by the browser calling a function we gave it when we made the request. Despite its name, the XMLHttpRequest object can be used to make a request in any form of data – in our case, we will be transferring our simple colon-separated tag-value format.

The first thing we need to do is get hold of an XMLHttpRequest object. Unfortunately, not all browsers do this in the same way. Most browsers implement an XMLHttpRequest object directly. Microsoft Internet Explorer prior to version 7 uses an ActiveX object. The following function works out which ways can be used, and returns an appropriate request object.

function get_request_object()
{
    if(window.XMLHttpRequest)
    {
        // This version for Firefox, Opera...
	  return new XMLHttpRequest()
    }
    else if(window.ActiveXObject)
    {
        // This version for Internet Explorer 6 and before
	  return new ActiveXObject("Microsoft.XMLHTTP");
    }
}

Making a request

When the user clicks on the button in the HTML form, we want to GET the full list of items from the server, and display them in the browser. The first part of this is making the request. In the <script> tag above, create the request function:

function view_all_items()
{
    request = get_request_object();

    // Set up the callback function: this is called when the request returns
    request.onreadystatechange = function() {
        // Insert the callback function code here
    };

    // Set up the request
    request.open("GET", "http://localhost:8080/auction/item", true);
    // Send the request
    request.send(null);
}

Handling the response from the server

So far, so good: the function simply creates an XMLHttpRequest object, tells it which function to call when it’s completed, and what HTTP method and URI to call. We now need to flesh out the request.onreadystatechange function. Where it says Insert the callback function code here, start adding the following code. First, we need to check that the function is being called back for completion of the full call (request.readyState == 4), and that the request was successful (request.status == 200).

if(request.readyState == 4)
{
    if(request.status == 200)
    {

The response from the server is in request.responseText. We split this up into lines, and then each line into a key and a value, separated by “:”. We put the key/value pairs into an object as we get them.

      var items = new Array(new Object());
	// Split up the results data into input lines
	var lines = request.responseText.split("\n");

	for(var dataitem in lines)
	{
	    var line = lines[dataitem];

	    // For each line of output, parse it and add it to
	    // an object representing that result
	    var parts = line.split(":", 2);

	    if(parts.length < 2)
	    {
	        items.push(new Object());
		continue;
	    }

	    items[items.length-1][parts[0]] = parts[1];
	}

Having parsed the data file, we can construct something that the browser can render. In this case, a table:

        // Construct a table to hold the results
    	var newlist = "";

	newlist += "<table>\n";
	newlist += "  <tr>\n";
	newlist += "    <th>Title</th>\n";
	newlist += "    <th>Description</th>\n";
	newlist += "    <th>Reserve</th>";
	newlist += "    <th>End date</th>";
	newlist += "    <th></th>";
	newlist += "  </tr>\n";

	for(var idx in items)
	{
	    var item = items[idx];

	    if(item['id'])
	    {
	        newlist += "  <tr>\n";
		newlist += "    <td>" + item['title'] + "</td>\n";
		newlist += "    <td>" + item['description'] + "</td>\n";
		newlist += "    <td>&pound;" + item['reserve'] + "</td>\n";
		newlist += "    <td>" + item['expiry'] + "</td>\n";
		newlist += "    <td></td>\n";
		newlist += "  </tr>\n";
	    }
	}

	newlist += "</table>";

Finally, we insert the table we have just constructed into the document being viewed in the browser. We insert it into the <div> in the HTML document, which acts as a placeholder. Note that the <div> has an id attribute, which allows us to find it directly in the HTML document with the getElementById() method.

        // Set the contents of the "itemlist" <div> to the results
	var target = document.getElementById("itemlist");
	target.innerHTML = newlist;
    }
}

Save the resulting auclient.html file, and test it by going to http://localhost:8080/auclient/auclient.html. If things go wrong, check your server logs (in $CATALINA_HOME/logs/catalina.out) for exceptions. In Firefox, you can see JavaScript errors in the client from the “Error Console”, available in the Tools menu.

Now that we have a working client that reads data from the server, we can move on to the task of adding items to the database.

Valid XHTML | Copyright | Last Modified: 1/Apr/2009 |