Java News Brief        
                                         September 2000 Issue                                        

Headlines: 
Java Technical Insight of the Month
    "A JSP Custom Tag for XML+XSLT" 

Visit  The Java News Brief Archive for past issues of the JNB.
OCI Educational Services
       
                
Java Technical Insight of the Month
A JSP Custom Tag for XML+XSLT
By Eric Burke, Senior Software Engineer, Object Computing, Inc. (OCI)

Overview

XML Notes...
Most of you probably already know that XML stands for eXtensible Markup Language. By itself, XML is just a format for storing data. XSLT, or eXtensible Stylesheet Language Transformations, is a companion technology which can transform XML data files into other formats, such as HTML.

XSLT is valuable for web applications because it allows the formatting to be completely separated from the underlying data. Changing a font or color is as simple as changing the XSLT stylesheet, which is itself an ordinary XML document.

Although there are other ways of generating web pages, such as embedding lots of println(...) statements into Servlets, these approaches are tedious to maintain. These approaches are also poorly adapted to multiple display formats.

With XSLT, on the other hand, you could apply one of several different stylesheets to the same XML data. This allows you to support different browser versions as well as the new generation of WAP enabled cell phones, all without changes to any of your Java code or underlying XML data.

The tag extension mechanism in Java Server Pages (JSP) version 1.1 allows programmers to extend the capability of JSP by creating custom tags. These custom tags, which utilize an XML-style syntax, remove the need to embed Java code directly into JSP pages. Non-programmers can focus on GUI layout, using a set of custom tags which were created by a separate team of programmers or else purchased from a vendor.

For example, here is how a custom tag could be used to display a standard company navigation bar: <oci:navbar currentPage="home" />. When the JSP is displayed to the client, the tag is expanded into an HTML table which displays the site navigation bar.

In this month's article, we examine how to create a custom JSP tag using the tag extension mechanism. Our tag will be much more interesting than a simple navigation bar, however. We will show how the tag extension mechanism can be used to treat JSP as an XML template engine, which removes the need to programmatically generate dynamic XML using the DOM API. Just like last month's article, we will use XSLT to transform the XML data into an HTML web page.

Terminology

Graphical Depiction of Terms
Fig 1 - Graphical Depiction of Terms

Example Usage

We will be creating a single custom tag. This tag will contain a well formed XML document that will be transformed into a web page using XSLT. The XSLT stylesheet will be specified using an attribute. The location must be relative to the web application's context root directory. Here is an example JSP:
<%@ taglib uri="/ocixml" prefix="oci" %>

<oci:xmlxslt xsltLocation="/viewEmployee.xslt">
  <employee>
    <firstName>Eric</firstName>
    <lastName>Burke</lastName>
    <function>Java and XML Instructor</function>
  </employee>
</oci:xmlxslt>
When the above example is viewed in a web browser, it is seen as an HTML page that shows details about the employee. Formatting is completely removed from the JSP, as is the need to use DOM or JDOM to create the XML document. One piece is missing: dynamic content!

The power of JSP lies in its templating capabilities. Rather than hard-code the values of the XML elements, the following example shows how to dynamically generate the XML. Code shown in blue represents data which is extracted from a JavaBeans component.

<%@ taglib uri="/ocixml" prefix="oci" %>
<jsp:useBean id="empBean" class="Employee">
    <jsp:setProperty name="empBean" property="empId"/>
    </jsp:useBean>

<oci:xmlxslt xsltLocation="/viewEmployee.xslt">
  <employee>
    <firstName><jsp:getProperty name="empBean"
        property="firstName"/></firstName>
    <lastName><jsp:getProperty name="empBean"
        property="lastName"/></lastName>
    <function><jsp:getProperty name="empBean"
        property="function"/></function>
  </employee>
</oci:xmlxslt>
That's really all there is to it. A separate XSLT stylesheet controls the formatting of the web page, removing the need to clutter up the JSP with fonts, headings, colors, and tables. You could even use this template mechanism to combine multiple XML documents and stylesheets using a single JSP. When the look-and-feel requirements change, you simply edit the XSLT stylesheet.

Creating the Custom Action

Custom actions are created by Java programmers. The JSP tag extension mechanism provides several classes and interfaces in the javax.servlet.jsp.tagext package to support this. The primary interfaces are Tag and BodyTag. Tag is used for simple tags that have no content. An example would be <oci:footer />.

A BodyTag is one which can contain child content. This content could be something as simple as a single line of text, or it could be many other nested tags.

TagSupport and BodyTagSupport are classes which implement the previously mentioned interfaces. In typical Java style, these are helper classes which you are supposed to extend. In our example, we need to extend BodyTagSupport because we need to define XML within the content area of our custom tag.

One reason we need to use a custom tag for this functionality is the fact that there is no other way in JSP to capture output before it is sent to the client browser. Without a custom tag, the XML content is simply sent to the browser before we have a chance to apply the stylesheet. With our custom tag, we can process the XML and then send the results back to the browser.

Here is the complete source code for the custom action:

import java.io.*;
import javax.servlet.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import org.apache.xalan.xslt.*;

/**
 * A custom action which allows the content of a tag, which contains
 * well-formed XML, to be converted to HTML using an XSLT stylesheet.
 */
public class XmlXsltTag extends BodyTagSupport {
    private String xsltLocation = "";

    public int doAfterBody() throws JspException {
        try {
            // the content of the custom tag contains the XML source
            XSLTInputSource xmlSource = new XSLTInputSource(
                    bodyContent.getReader());

            // locate the XSLT stylesheet
            ServletContext sc = pageContext.getServletContext();
            XSLTInputSource stylesheet = new XSLTInputSource(
                    sc.getResourceAsStream(xsltLocation));

            // prepare to write the resulting HTML back to the browser
            JspWriter out = getPreviousOut();
            XSLTResultTarget resultTree = new XSLTResultTarget(out);

            XSLTProcessor processor = XSLTProcessorFactory.getProcessor();
            processor.process(xmlSource, stylesheet, resultTree);

            // inform JSP that it does not need to continue processing 
            // the body of this custom tag
            return Tag.SKIP_BODY;
        } catch (org.xml.sax.SAXException saxEx) {
            throw new JspException("SAXException: " + saxEx.getMessage());
        }
    }

    /**
     * A setter method for the "xsltLocation" attribute
     */
    public void setXsltLocation(String xsltLocation) {
        this.xsltLocation = xsltLocation;
    }

    /**
     * A getter method for the "xsltLocation" attribute
     */
    public String getXsltLocation() {
        return this.xsltLocation;
    }

    /**
     * Reset the state of this object to default values in case
     * JSP reuses the instance.
     */
    public void release() {
        super.release();
        this.xsltLocation = "";
    }
}

TLD File

The Tag Library Descriptor (TLD) is an XML file which describes the contents of a tag library. The complete format is described in the JSP specification. For now, the required features are: Once the TLD file has been created, it is packaged up in a JAR file along with any Java classes which represent the custom actions.

Deployment Descriptor

The deployment descriptor (web.xml) is a required part of any web application. A simple entry in the deployment descriptor is required for each tag library. This entry contains the following information:

Putting the Pieces Together

If you recall from the JSP examples above, the first line of the JSP file must reference the taglib. The uri attribute is actually the alias which you listed in the deployment descriptor:
<%@ taglib uri="/ocixml" prefix="oci" %>
The prefix is essentially an XML-style namespace prefix. This allows you to avoid naming conflicts when using tag libraries from different vendors.

Here is another diagram which shows how all of these configuration files and aliases fit together: Configuration Files

Learning More

This article covered a lot of ground in a very small space. The tag extension mechanism is extremely powerful and correspondingly complex. Most books on JSP do not do justice to this very important topic, despite the fact that this is the best (and often only) way to cleanly separate programming logic from presentation in your JSPs.

"Web Development with JavaServer Pages" by Manning Publications provides an excellent coverage of the tag extension mechanism. All features are covered in detail, with plenty of examples. The other "must read" document is the JSP 1.1 specification from Sun. Just visit http://java.sun.com/products/jsp and look for the specs.

OCI's new course, "Advanced Servlets and JSPs", covers all aspects of this important topic. We start with a basic empty tag that has no attributes, and progressively build until every feature of the tag extension mechanism has been covered. The first Open Enrollment offering of this course is in November, 2000. Send Email to training for more details.

Downloading the Code

To download complete source code, visit http://www.ociweb.com/jnb/files. The code example contains a README file which describes how to compile and run everything. The requirements are as follows:
Valid XHTML 1.0 Strict [Valid RSS]
RSS
Top