 | Level: Intermediate Daniel Wintschel (daniel@humandoing.net), Writer and developer, Freelance
23 Oct 2007 Developers and users have much higher expectations for the usability and
responsiveness of Web-based applications in the Web 2.0 era. Unless you've been
living under a rock for the past two years, you've likely heard of Asynchronous
JavaScript + XML (the Ajax technique). Ajax allows you to build slick, responsive,
and highly dynamic browser-based user interfaces without requiring browser page
reloads. This article takes a look at AjaxTags, a Java™/JavaScript Library that lets you easily integrate Ajax functionality into your JSP pages.
Introduction
Traditionally, Web-based user interfaces (including both pages and applications) have required that each request made by the user forced a page refresh, consuming a considerable amount of time and bandwidth. Repeated page refreshes can result in a fairly slow and clunky Web experience, even for users with the fastest broadband connection available.
These days, developers everywhere are flocking to new tricks and techniques to drastically improve the performance and user experience within Web-based applications. Web applications coded with Ajax can allow data to be sent to the server asynchronously in the background, while simultaneously updating various parts of the Web page being viewed without a page reload. Ajax comprises a number of objects and technologies. And despite the X initial in the acronym Ajax, XML might never be used at all. The response sent back from the browser could be one of various types or formats, including but not limited to plain text, HTML, or XML.
This article describes a compact little JSP tag library that uses some external
JavaScript to bring easy-to-use Ajax support to your JSP pages: AjaxTags.
Getting started
If you want to follow along and run the examples described in this article, you'll need to pick up a few tools. Every application you use here is freely available and open source.
 | | Building Ajax functionality into your applications can be a great benefit to your users in several ways and can often ease development complexity as well. Libraries like AjaxTags and well-tested JavaScript libraries can do a lot of the heavy lifting for you. |
|
Apache Tomcat is the reference implementation servlet container that you'll be using to run the examples presented in this article. You can download it freely from the Apache Tomcat Web site (see Resources). The examples in this article use the latest version, which at the time of writing is 6.0.13.
You also need to head over to SourceForge to download the AjaxTags example application (see Resources for a link). The examples here use version 1.3 of the Ajax Tags demo download. This is a standard WAR file that you can deploy into the Tomcat webapps directory. Rename the WAR file before you deploy it if you don't want the URL that you have to browse to be clunky. Otherwise, you need to browse to: http://localhost:8080/ajaxtags-1.3-beta-rc6-1/.
Let's get started.
Isn't Ajax for cleaning bathtubs?
Just a few years ago, even die-hard developers associated the name Ajax with the popular cleanser developed and manufactured by Colgate-Palmolive, and not a Web development technique that improves online experiences. Now that Ajax the technique is gaining popularity, you probably want all the information you can get on how it works and what sort of situations you might use it in.
How does this work?
When you're developing and coding an Ajax application, you need to understand what happens in both the foreground and the background. A typical flow of events within an application might look something like the following:
- User requests a Web page.
- User makes changes to the state on the Web page (for example, clicking a link, choosing something from a select box, clicking a radio button or check box).
- The change of state results in an event being fired, calling a JavaScript function.
- The JavaScript function instantiates an
XmlHttpRequest object, which asynchronously makes an HTTP request to a server in the background (note that no page refresh occurs).
- The server responds, returning the requested data to the JavaScript function.
- The JavaScript function updates and modifies the current page being viewed through the use of additional JavaScript and/or DHTML.
The JavaScript that is responsible for updating portions of the currently viewed Web
page needs to know which HTML elements it is responsible for updating. To actually
update specific elements within a given page dynamically (read: without reloading the page), you assign these HTML elements a unique ID. A simple example from the demo that you'll look at more in depth shortly is shown in Listing 1:
Listing 1. Simple example of assigning an ID to an HTML element
<select id="model" disabled="disabled">
<option value="">Select model</option>
</select>
|
Listing 1 assigns the ID of model to this particular select box. Using the ID, you can easily locate and manipulate the selected element and its contents using JavaScript.
You'll be pleased to know that the AjaxTags API uses some very well-written, open source, third-party JavaScript libraries that do almost all of the heavy lifting for you. The advantage of this is that these libraries are packed with rich features and are extensively tested in numerous browsers, so you can rest assured they're going to work. The third-party libraries used by AjaxTags include:
- Prototype (a JavaScript library with piles of utility functions)
- Script.aculo.us (a JavaScript library full of visual effects)
- Overlibmws (a DHTML pop-up library)
When to use AjaxTags
You might want to use AjaxTags in a number of typical situations where you not only want to make things easier for yourself as a developer but also improve the user experience for those using your application. Some of these use cases include:
- Modifying the contents of a secondary drop-down box based on a selection made in the first
- Initiating a request for additional information from the server based on a click or a mouseover event without refreshing the page the user is viewing
- Performing calculations on the server based on user-entered data without reloading the entire page
Let's get started looking at some actual examples of how to integrate some of these features into an application.
Integrate AjaxTags into your application
To integrate AjaxTags into one of your own applications, a few prerequisites are necessary. This section covers these prerequisites and dependencies.
Dependencies
Your best bet when downloading and using AjaxTags is to download the entire binary distribution, and not just the JAR file. That way, you get all of the required dependencies bundled with it including the Prototype, Script.aculo.us, and overlibmws libraries.
Setup and configuration
The setup and configuration of AjaxTags for use in your own applications is very straightforward:
- Place the ajaxtags.jar file into your WEB-INF/lib directory.
- If you're using an older servlet container (prior to Servlet 2.4 / JSP 2.0), you need
to add a taglib definition to your web.xml file; if you're using a newer container, you don't have to worry about it.
Listing 2. Tag library definition for older servlet containers (add to web.xml)
<taglib>
<uri>http://ajaxtags.org/tags/ajax</uri>
<location>/WEB-INF/ajaxtags.tld</location>
</taglib>
|
- Copy the dependency JavaScript files into your Web application. According to the AjaxTags documentation, you need:
- Prototype 1.4.0: prototype-1.4.0.js
- Scriptaculous 1.5.1: scriptaculous.js, builder.js, controls.js, dragdrop.js,
effects.js, and slider.js
- OverLIBMWS (optional, for ajax:callout only): overlibmws.js
Once you complete these main steps, you should be able to start using the AjaxTags JSP tag library in your application. From the development side, the two main things you need are a JSP page (the view), along with a server-side data handler that is capable of returning appropriate content to the asynchronous call received by the client.
AjaxTags deals with XML, HTML, and plain text content by default, which should cover most user needs. The API itself contains some helper classes for constructing the appropriate responses with very few lines of code.
AjaxTags demo and samples
The AjaxTags demo application downloaded from SourceForge has numerous real world
examples. Let's take a look at a few of these now; they should give you great ideas on how you can easily integrate similar features, rather painlessly, into your own applications.
Note:The samples you're looking at are using hard-coded data sources. In the real world, you'd be pulling data from a database instead of data that is hard-coded in your Java files.
Select box update, view, and HTML
Let's start at the client side, where you can walk through how the whole process works from front to back. The first thing you'll look at is a snippet from a demo JSP that contains a couple of drop-down boxes. This is what the relevant part of the page looks like (you can find this by browsing to the AjaxTag demo application running within your Tomcat instance and clicking Run on the Select/Dropdown example). This is a particularly good example because it utilizes pre- and post-JavaScript functions, as well as a progress indicator. It also displays the car maker's logo once you've made an appropriate selection (see Figure 1).
Figure 1. Drop-down sample page
As you can see, there are two drop-down boxes. Let's take a look at the relevant JSP
code (found in dropdown.jsp) used to make this happen (see Listing 3):
Listing 3. HTML select boxes from dropdown.jsp
<label for="make">Make:</label>
<select id="make">
<option value="">Select make</option>
<option value="Ford">Ford</option>
<option value="Honda">Honda</option>
<option value="Mazda">Mazda</option>
</select>
<span id="progressMsg" style="display:none;">
<img alt="Indicator" src="<%=request.getContextPath()%>
/img/indicator.gif" /> Loading...</span>
<label for="model">Model:</label>
<select id="model" disabled="disabled">
<option value="">Select model</option>
</select>
|
Note the IDs given to the select elements and that the second drop-down has no car models in it and is disabled.
Select box update, a closer look at the JSP tag syntax
Now, let's take a look at the meat of this application that does all the work for you:
the actual usage of the AjaxTags JSP tag library. Listing 4 is taken from within the same file (dropdown.jsp):
Listing 4. AjaxTag JSP tag library sample: ajax:select tag
<ajax:select
baseUrl="${contextPath}/dropdown.view"
source="make"
target="model"
parameters="make={make}"
preFunction="initProgress"
emptyOptionName="Select model"
postFunction="resetProgress"
errorFunction="reportError" />
|
Before you go through the chunk of code in Listing 4, notice the following snippet:
${contextPath}. To clear up any confusion, this is actually a variable set using the EL (expression language) and is defined in header.jsp, as shown in Listing 5:
Listing 5. Definition of contextPath variable in header.jsp
<c:set var="contextPath" scope="request">
${pageContext.request.contextPath}</c:set>
|
I show this so you can see clearly how the ${contextPath} variable is being resolved. Its value is the equivalent of pageContext.getRequest().getContextPath() if you were spelling it out in Java code. All told, the ${contextPath} variable ends up with the value of http://localhost:8080/ajaxtags-1.3-beta-rc6-1 based on my configuration.
Refer back to Listing 4 now and note that to make an asynchronous callback to the server, you have to know the URL to request. AjaxTags requires this baseUrl parameter, which is the URL that is going to be requested asynchronously when a change event occurs to the select box with an ID of make.
Given that you know the value of ${contextPath}, you can see that the baseUrl that is going to be requested is http://localhost:8080/ajaxtags-1.3-beta-rc6-1/dropdown.view.
Following baseUrl, you have source and target. These parameters represent the ID of the HTML elements that you are acting on. In this case, you're acting on two select boxes: one that contains car makes and one that contains car models. The select box with car makes is the source and the select box with car models is the target.
The parameters parameter (see Listing
6) indicates additional parameters that should be passed along to the URL that is going to be requested:
Listing 6. The parameters parameter
Note the syntax of curly brackets as make={make}. What this
basically says is to append the parameter key of make to the URL that is being requested asynchronously, and as the value, pass whatever the value is that you find in the correspondingly named HTML element (based on the ID). So in this example, the behind-the-scenes-JavaScript is going to get the HTML element with the ID of make, get the value of that element, and pass it along as part of the HTTP request. This sounds much more confusing than it actually is, so let's look at the final URL that is going to be requested when a selection is made from the first select box (see Listing 7):
Listing 7. URL that will be requested when user selects "Mazda" from the first select box
http://localhost:8080/ajaxtags-1.3-beta-rc6-1/dropdown.view?make=Mazda
|
You can see that a parameter has been added to the end of the URL, and the parameter key is make, while the parameter value is Mazda.
The ajax:select parameters preFunction, postFunction, and errorFunction are simply the names of custom JavaScript functions that you've written, which are called appropriately as the timing or condition presents itself. In this case, the naming is obvious. The preFunction is executed before the Ajax request; the postFunction is executed after the Ajax request is complete and a response has been received, and errorFunction is executed if a problem occurs (such as the request returning a 500 Internal Server Error, or a message that the resource does not exist, and so on).
The last parameter, emptyOptionName, is the value of the
option that indicates a selection has not been made. In this case, the default state is restored.
After you've used a browser to request this JSP page, you'll notice that the
ajax:select tag has been replaced by the snippet of JavaScript in Listing 8, which is embedded within the page on the client (retrieved by viewing the source of the page in my Web browser):
Listing 8. JavaScript generated from the ajax:select tag
<script type="text/javascript">
new AjaxJspTag.Select(
"/ajaxtags-1.3-beta-rc6-1/dropdown.view", {
parameters: "make={make}",
postFunction: resetProgress,
target: "model",
preFunction: initProgress,
source: "make",
emptyOptionName: "Select model",
errorFunction: reportError
});
</script>
|
Basically, this snippet of JavaScript is executed as your browser evaluates it. A JavaScript object (AjaxJspTag.Select) is instantiated, and the appropriate listeners are attached to appropriate elements.
Let's quickly take a look at the actual response that is sent to the browser in the
background when the URL asking for vehicles with the make Mazda is requested, shown in Listing 9. (This response is the result of requesting the URL found in Listing 7.)
Listing 9. Ajax response
<ajax-response>
<response>
<item>
<name>Mazda 3</name>
<value>Mazda 3</value>
<value>false</value>
</item>
<item>
<name>Mazda 6</name>
<value>Mazda 6</value>
<value>false</value>
</item>
<item>
<name>RX-8</name>
<value>RX-8</value>
<value>false</value>
</item>
</response>
</ajax-response>
|
Select box update: a look at the server side
The server side code for the example is amazingly simple. The AjaxTag API has some
built in HttpServlet subclasses for your use should they suit your needs, as well as utility classes for generating simple XML responses (see Listing 10):
Listing 10. Snippet from DropdownServlet demonstrating the creation of an appropriate XML response to an Ajax request
public String getXmlContent(
HttpServletRequest request, HttpServletResponse response)
throws Exception {
String make = request.getParameter("make");
CarService service = new CarService();
List<Car> list = service.getModelsByMake(make);
AjaxXmlBuilder xml = new AjaxXmlBuilder();
for (Car car:list) {
xml.addItem(car.getModel(),true,car.getModel(),false);
}
return xml.toString();
}
|
I've slightly modified the code in Listing 10 from the example to simplify it. As you can see, there is very little code involved (and it could be reduced even further) to create an appropriate response that can be handled by the AjaxTags client-side JavaScript.
Summary
As you can see, AjaxTags makes it very easy for you to add powerful Ajax features to
either new or existing Java Web applications. With a full complement of JSP tags
providing support for drop-down box modifications, toggling, tab panels, callouts, and a
host of other features — AjaxTags makes an excellent choice for quick, easy, and sophisticated Ajax applications. Using Ajax libraries like AjaxTags can help greatly improve the usability and user experience of your Web applications, in addition to reducing server load and bandwidth usage.
Resources Learn
-
Take a look at a short tutorial on AjaxTags and AppFuse.
-
Read another short AjaxTags tutorial.
-
For a tutorial on learning how to develop and design Web applications based on Ajax, see "Build apps using Asynchronous JavaScript with XML" (Naveen Balani and Rajeev Hathi, developerWorks, November 2005).
-
Learn about some common coding practices to avoid in "Ajax and XML: Five Ajax
anti-patterns" (Jack D. Herrington, developerWorks, March 2007).
-
Explore five common Ajax design patterns that you can use as a basis for your own work in
"Ajax and XML: Five
common Ajax patterns" (Jack D. Herrington, developerWorks, March 2007).
-
This five-part series introduces a ground-breaking approach to creating dynamic Web
application experiences using Ajax: "Ajax for Java developers: Build dynamic Java applications" (Philip McCarthy, developerWorks, September 2005).
- The
developerWorks XML zone is packed with resources to get you started with XML.
-
Check out the developerWorks Ajax resource
center, your one-stop shop for information about the Ajax programming model,
including articles and tutorials, discussion forums, blogs, wikis, events, and news.
Get products and technologies
Discuss
About the author  | |  | Daniel Wintschel has a different bio every day. But mostly he likes helping small- and medium-sized businesses to be strong and efficient. Usually involving a healthy dose of Web applications in either the Java language or Ruby, he really likes coding. A lot. |
Rate this page
|  |