URL of the article:

Dynamic Content Creation
Techniques for Making Your Content More Interactive
By Alan M Berg
Numerous JSP tags use JavaScript to help make their content more vibrantly interactive. Technologies such as AJAX allow for partial page updates and increasing responsiveness. This article delivers an overview of a number of Open Source projects that have the potential to make your content more dynamic and interactive.

Introduction
In this article, I will be focusing on making web content more dynamic and alive. Firstly, I will discuss the use of JavaScript . Pure JavaScript solutions represent one extreme of the thick, thin client server spectrum. Unnecessary communication with the server is removed. With dynamic updating of images, richer and more life-like GUIs can be generated. Making a GUI yourself is a potentially costly effort. However, using Open Source toolkits may put you in place for Rapid Application Development (RAD) where you can build the GUI first and plug in the server-side code later. The Dojo toolkit [2] allows for the creation of dynamic JavaScript widgets. In the first section, I will describe how to apply the toolkit to make an interactive menu and to render a cool text editor. Secondly, I shall mention two JSP tag libraries: Taconite [4] and the obviously named AJAX tag library [5] . The Taconite framework pulled at my attention due to its elegance and the author's knowledge of the weaknesses of current AJAX implementations. (I believe this framework deserves to become the basis for many other well-formed tag libraries in the future.) The taconite framework is well made, but somewhat sparse in the richer features that take advantage of partial updating. The AJAX JSP tags have a richer set of instantly usable features. The tag library allows for auto completes, tabs, event triggering, and so on. That is exactly what you would expect from a serious competitor in this popular field. I will describe one basic example of building a portal to highlight the general viability of AJAX.

Back to Basics
A significant negative of using scripting solutions in browsers are those subtle (and not so subtle) compatibility issues. This is also true for AJAX methodologies that require a scripting language to allow communication to occur between the web browser and the server. Listing1 highlights this point. The generated HTML page returns the current year plus the browser version. For Internet Explorer (IE) that is defined in a meaningful but non-standard way, it is the exact year and for Firefox, the number of years since 1900. What does this mean? Imagine that you seek a web form that has a `select' box with the last ten years as values. You have two choices - hard code the select box or write JavaScript that reads in the year and loops through a number of values. In the code, you will need to detect browser type and take into account different interactions. The greater the volume scripting of code you write, or the more complex the Graphical User Interface (GUI), the more code that needs to be set aside for browser detection. In this situation, choosing a toolkit for GUI building makes sense. Large projects tend to have greater developer effort. The more developers that are working on a toolkit, the greater the chance those inconsistent renderings are removed.

Listing 1: A simple JavaScript that returns different results depending on browser type

<html><head><title>Example browser differences</title></head>
<body>
<form>
<script LANGUAGE="JavaScript">
document.write('<b>Supposed browser type: </b>'+navigator.appName+'<br>');
document.write('<b>Version: </b>'+navigator.appVersion+'<br>');
document.write('<b>The year is: </b>' + new Date().getYear()+'<br>');
</script>
</form>
</body>
</html>

These are the returned results from the code shown in Listing 1 , for IE and Firefox 1.5:

<b>Supposed browser type</b>: Microsoft Internet Explorer
<b>Version</b>: 4.0 (compatible; MSIE 6.0; Windows NT 5.1; CHWIE_NL70; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)
<b>Year</b>: 2006

<b>Supposed browser type</b>: Netscape
<b>Version</b>: 5.0 (Windows; en-US)
<b>Year</b>: 106

AJAX, among other features, enables the dynamic updating of part of an otherwise static page. This allows for behaviors such as auto completion of text input boxes and the on-demand filling of data into tables, which a typical database application requires. The end results are richer, more interesting, and responsive GUIs at lower bandwidths than full page updates. Unfortunately, AJAX also has browser specific features. For example, to create a relevant object in IE, your code would look like this:

IE5: var myRequest = new ActiveXObject(“Microsoft.XMLHTTP”)
IE5: var myRequest = new ActiveXObject(“Msxml2.XMLHTTP”)
Safari or Mozilla: var myRequest= new XMLHttpRequest()

Other browser types may have other means to achieve the same end. Luckily, the W3C has developed a viable and potentially unifying standard . In the meantime, it is better to use frameworks or JSP tag libraries that push some of the ugly wiring under the carpet. This is the price we pay for using browsers that do not fulfill the full range of open standards.

The DOJO Toolkit
The DOJO Open Source JavaScript toolkit allows for rapid design and implementation of HTML CSS widgets. At present, there are over 20 widgets supported. The product has strong cross browser compatibility and has been thoroughly tested under; IE 5.5+, Mozilla 1.2+, Firefox 1.0+, Safari 1.3.9+, Konqueror 3.4+, and Opera 8.5+ Better still, the toolkit supports AJAX and event handling, and handles packaging of the widgets within a well-defined and systematic structure. In this section, I will briefly mention two widgets= - a rich text editor as shown in Figure 1 and a snazzy animated menu generator ( Figure 2 ). Listing 2 is a highly simplistic HTML page that allows you to type into a text area and format the typed corpus with a rich text editor. Loading in the script is straightforward. You simply mention the term dojo.js . To load in a particular widget, use the dojo.require stanza. Defining which parts of the functionality should be enabled is achieved via the items=”” attribute.

<html><head><title>DOJO EDITOR TEST</title>
<body>
<script src="dojo.js" type="text/javascript"></script>
<script type="text/javascript">
dojo.require("dojo.widget.Editor");
</script>

<form>
<textarea dojoType="Editor" name="editorContent"
items="bold;italic;underline;strikethrough;">
Please fill here ....


Figure 1: Screen grab of the rich text editor generated via Listing 2

As part of the archived code included in this article, /dojo/menu.html generates a fish-eyed menu ( Figure 2 ). To connect a menu item to your own JavaScript function is rather straightforward. Modify the onClick event of the div class dojo-FisheyeListItem . Modifying the image requires changing the attribute dojo:icosrc. and changing the caption of the specific menu item via the attribute caption. Adding an extra item is easy, just add another <div> with the series of already present and related divs. For example:

<div class="dojo-FisheyeListItem" onClick="load_app(X);"
dojo:iconsrc="img/X.gif" caption="MenuX">
</div>


Figure 2: An example of a fish-eyed menu

The Dojo framework has an aggressive roadmap. It is worth revisiting the site mentioned in the Resources section periodically for updates.

The Taconite Framework
Taconite, otherwise known as iron ore, is a fundamental raw material for many products including iron and stainless steel. Similarly, the Taconite framework is the raw material that helps you build complex AJAX infrastructures. Though relatively empty in wiz bang enhanced JSP tags, the framework does the basics very well, hiding the browser specific details and mimicking the W3C standard to a great degree. One approach to add dynamic updates is to use the Taconite JavaScript libraries in an HTML page that call a JSP page containing Taconite JSP tags. The servlet being a JSP and the client, JavaScript, allow for a rapid development cycle without the need to continually redeploy war files. Listing 3 is a basic HTML page. Communication is achieved via the AjaxRequest object, instanced via the doHelloWorld function. The placeholder for the returned information is the
. The ID will be mentioned in a JSP tag later. This approach allows you to place div elements in the page and have multiple update locations depending on the events triggered.

Listing 3: Taconite framework AJAX request

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Taconite Example</title>
<script type="text/javascript" src="taconite-client.js"></script>
<script type="text/javascript" src="taconite-parser.js"></script>
<script type="text/javascript">
function doHelloWorld(url) {
//Create AjaxRequest object
var ajaxRequest = new AjaxRequest(url);
ajaxRequest.sendRequest(); //Send the request
}
</script>
</head>
<body>
<a href="javascript:doHelloWorld('test.jsp');">Hello World</a>
<br/>
<table border=5><tr><td>HELLO WORLD</td></tr>
<tr><td><div id="helloWorldContainer" /></td></tr>
</table>
</body>
</html>

Listing 4 returns a counter value to the div mentioned in the previously defined HTML code. There are a number of points of interest here: The first is that data consistency is being enforced via the is ThreadSafe="false" pragma and synchronization. The second is that the returned information needs to be valid XHTML and hence, the use of the fully paired
tag. (Remember to escape data you are unsure about.) The taconiteRoot tag contains an appendAsChildren tag. Every time a response is sent back, the value is appended to the XHTML DOM [7] node. Other content delivery tags include the actions - append as children, append as first child, delete, insert after, insert before, replace children, replace. A significant feature to note is the choice in parsing methods. The first is on server side JSP. The parser generates more verbose responses, but because servlets follow a well-known and precise standard, the end result is consistent and browser independent. Parsing can also be done via the Taconite JavaScript parsing library. This creates a less verbose and thus generally faster response. However, if there are inconsistencies in the way the browser types interpret the JavaScript, you may have an on-rolling maintenance issue. The best approach is to parse on the client and if issues occur, bite the bullet and move over to server side parsing. This feature is turned on and off via the parseOnServer attribute.

Listing 4: A JSP that returns information via the appendAsChildren tag

<%@ taglib uri="http://taconite.sf.net/tags" prefix="tac" %>
<%@ page isThreadSafe="false" %>

<%! int count=0;%>
<%synchronized(this){count++;}%>

<tac:taconiteRoot>
<tac:appendAsChildren contextNodeID="helloWorldContainer" parseOnServer="true">
<br/>Total request(s):<%=count%>
</tac:appendAsChildren>
</tac:taconiteRoot>

In terms of reliability, Taconite looks like a thoroughly well thought-out and engineered framework. Taconite elegance comes at the cost of feature richness. In the next section, I will look at the AJAX tag library.

AJAX Tags
The AJAX tag library includes a rich collection of viable tags. The list includes tabbed panels, portlets, updating of form fields, selects and auto completion. In this section, I will build a simple fully channelled page based on the portlet tag. Each channel will update itself regularly. Portlets are defined in JSR 168 [8] and enable channels to be made in a consistent and standard way. Although the portlet tag is not consistent with the standard, the tag mimics similar functionality. Please note that for proper portleting, look towards products such as Pluto [9] . Pluto is an example for portlets and is used thoroughly within the newest versions of the freely available uPortal system. Listing 5 generates the rendered page ( Figure 3 ). Firstly, we shall point to the AJAX and JSTL tag libraries. Next, we try and enforce no-caching via setting the HTTP header Cache-Control to no-cache. Otherwise, we may end up with a static rather than a dynamic page. Using JSLT, we define the contextPath . This allows the deployed WAR file to be anywhere, since we can point to the required JavaScript files relative to the context path. The AJAX tag library requires a number of JavaScript files, including Scriptaculous [10] . Creating a time stamp via <%=new java.util.Date()%> allows the viewer of the page to see that the top part of the page is not being updated despite the fact that the channels are. The portlet tag mentioned next, calls the ${contextPath}/servlet/Random Servlet periodically every two seconds. A return result of an HTML fragment is expected.

Listing 5: JSP that creates an elementary portal

<ajax:portlet
source="portlet_1"
baseUrl="${contextPath}/servlet/Random?portlet_stock"
classNamePrefix="portlet"
title="STOCK PRICE"
imageClose="img/close.png"
imageMaximize="img/maximize.png"
imageMinimize="img/minimize.png"
imageRefresh="img/refresh.png"
refreshPeriod="2" />


<%@ taglib uri="http://ajaxtags.org/tags/ajax" prefix="ajax" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%response.setHeader("Cache-Control","no-cache");%>
<c:set var="contextPath" scope="request">${pageContext.request.contextPath}</c:set>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>AJAX JSP Tag Library Example</title>
<script type="text/javascript" src="${contextPath}/ajax_jsp/js/prototype-1.4.0.js"></script>
<script type="text/javascript" src="${contextPath}/ajax_jsp/js/scriptaculous.js"></script>
<script type="text/javascript" src="${contextPath}/ajax_jsp/js/overlibmws.js"></script>
<script type="text/javascript" src="${contextPath}/ajax_jsp/js/ajaxtags.js"></script>
<link rel="stylesheet" type="text/css" href="css/ajaxtags-sample.css" />
</head>
<body>
<h3>My Portal</h3>
<h4><%=new java.util.Date()%></h4>

<div id="portletArea">
<table border=1><tr><td>
<ajax:portlet
source="portlet_1"
baseUrl="${contextPath}/servlet/Random?portlet_stock"
classNamePrefix="portlet"
title="STOCK PRICE"
imageClose="img/close.png"
imageMaximize="img/maximize.png"
imageMinimize="img/minimize.png"
imageRefresh="img/refresh.png"
refreshPeriod="2" />
</td><td>
<ajax:portlet
source="portlet_2"
baseUrl="${contextPath}/servlet/Random?portlet_weather"
classNamePrefix="portlet"
title="WEATHER"
imageClose="img/close.png"
imageMaximize="img/maximize.png"
imageMinimize="img/minimize.png"
imageRefresh="img/refresh.png"
refreshPeriod="3" />
</td></tr><tr><td>
<ajax:portlet
source="portlet_3"
baseUrl="${contextPath}/servlet/Random?portlet_units"
classNamePrefix="portlet"
title="UNITS SOLD"
imageClose="img/close.png"
imageMaximize="img/maximize.png"
imageMinimize="img/minimize.png"
imageRefresh="img/refresh.png"
refreshPeriod="5" />
</td></tr></table>
</div>
</body>
</html>

Listing 6 is a Java class that returns HTML fragments with random stock, weather or units sold data. This class is called from the servlet mentioned in Listing 7 . (The code is a placeholder for more sophisticated datasource logic.)

Listing 6: Placeholder helper code that returns random data in HTML fragments

package playground.berg.helper;
import java.util.Random;

public class DataHelper {
Random random;
int counter;

public DataHelper(){
random= new Random();
counter=0;
}

public synchronized String getPortletFragment_stock(){
return "Random Stock value = <b>"+this.random.nextInt(2000)+" eu</b>";
}

public synchronized String getPortletFragment_weather(){
return "Random Temperature = <b>"+this.random.nextInt(50)+" C</b>";
}

public synchronized String getPortletFragment_units(){
return "UNITS SOLD <b>"+this.counter++ +" UNITS</b>";
}
}

Listing 7 produces random data depending on the incoming URL. Noe how elementary and straightforward the code is. Setting the header value Cache-Control to no no-cache is not necessary, but has been included because it appears to remove artifacts from rendering in IE5 that was not seen in Firefox 1.5. (Check against updates that go through proxies.) Caching at the proxy may require additional handling in the HTTP header of the servlet response.

Listing 7: Simplified Java Servlet that returns HTML fragments

package playground.berg.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import playground.berg.helper.DataHelper;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class RandomDataServlet extends HttpServlet {
private static final long serialVersionUID = -1435911911678930690L;
private final String errorMsg="<h2>Unexpected Input</h2>";
DataHelper helper;


public RandomDataServlet() {
super();
this.helper=new DataHelper();
}

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
response.setHeader("Cache-Control","no-cache");
response.setContentType("text/html");
if (request.getParameter("portlet_stock")!=null){
out.println(this.helper.getPortletFragment_stock());
}else if (request.getParameter("portlet_weather")!=null){
out.println(this.helper.getPortletFragment_weather());
}else if (request.getParameter("portlet_units")!=null){
out.println(this.helper.getPortletFragment_units());
}else{
out.println(errorMsg);
}
out.flush();
out.close();
}
}


Figure 3: Screen grab of simple portlet functionality

The portlet example uses HTML fragments. Traditionally, AJAX is all about sending XML compliant messages from the server. A nice generic feature of the tag library is its ability to understand comma delimited data as well as XML. I hope that the demonstration code has given you an idea of the tag library's potential. I look forward to seeing the library's vocabulary expanded over the course of time.

General Conclusions
The Open Source community has provided numerous opportunities to enhance content in a dynamic way. In this article, I have mentioned as examples DOJO, Taconite, and the AJAX tab library. Those of you who wish to look further into the field must know that the Myfaces JSF [11] project also includes a number of AJAX technologies; with the project's relatively high velocity of change, it is worth periodically checking for updates.

Concluding the Series
In this series of articles over Open Source JSP libraries, the tag libraries have been put through their paces. From these articles, I hope that you conclude that there are numerous high quality products in the market and that libraries are relatively easy to understand and implement. Searching around, I was impressed by the velocity of change and responsiveness that the Open Source community delivers to the market. I hope I have captured the feeling of quality through diversity. Finally, it seems fit to me to point out one last product. Yesterday, I noticed another fun project - the Google Maps JSP library [12] - mentioned in the Resources section. No doubt, if I perform a market survey in a month's time, a few more exciting projects will pop up. Yes, these are interesting times.
Author Bio: Alan Berg, Bsc. MSc. MSc. PGCE, has been a lead developer at the Central Computer Services at the University of Amsterdam for the last seven years. In his spare time, he writes computer articles. He has a degree, two masters and a teaching qualification. In previous incarnations, he was a technical writer, an Internet/Linux course writer, and a science teacher. He likes to get his hands dirty with the building and gluing of systems. He remains agile by playing computer games with his kids who (sadly) consistently beat him. You may contact him at reply.to.berg@chello.nl

Resources

© 2004 Software & Support Verlag GmbH. Reproduction has to be permitted by the publisher. Questions?