A JSP Custom Tag for XML+XSLT

A JSP Custom Tag for XML+XSLT

By Eric Burke, OCI Senior Software Engineer

September 2000


Overview

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

Some Notes on XML ...

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 that can transform XML data files into other formats, such as HTML.

XSLT is valuable for web applications because it allows 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.

Terminology

Custom Action
JSP includes six standard actions, such as <jsp:include .../>. Custom actions are new actions created by programmers, extending the capabilities of JSP. Two interfaces are provided for the creation of custom actions: Tag and BodyTag.
Custom Tag
This is the markup that invokes a custom action. Custom tags use XML syntax and are what page authors use.
Tag Extension Mechanism
This is an umbrella term that describes the set of classes and conventions that allow programmers to create custom actions and tags within JSP. The tag extension mechanism was added to JSP in version 1.1.
Tag Library
A collection of custom actions and tags, packaged into a JAR file. Although Sun does not define any standard tag libraries for JSP, many open source efforts are under way to define "standard" tag libraries for database access, formatting, looping, and other common tasks.
Tag Library Descriptor (TLD)
The TLD is an XML file that describes the contents of a tag library. In addition to defining aliases for tags, the TLD defines constraints on tags, such as whether or not attributes are allowed.
XSLT
A stylesheet language for performing transformations on XML documents. In this example, an XSLT stylesheet is a separate document that converts the XML into an HTML web page.

Fig 1: 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:

  1. <%@ taglib uri="/ocixml" prefix="oci" %>
  2.  
  3. <oci:xmlxslt xsltLocation="/viewEmployee.xslt">
  4. <employee>
  5. <firstName>Eric</firstName>
  6. <lastName>Burke</lastName>
  7. <function>Java and XML Instructor</function>
  8. </employee>
  9. </oci:xmlxslt>

When the above example is viewed in a web browser, it is seen as an HTML page that shows details about an 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 extracted from a JavaBeans component.

  1. <%@ taglib uri="/ocixml" prefix="oci" %>
  2. <jsp:useBean id="empBean" class="Employee">
  3. <jsp:setProperty name="empBean" property="empId"></jsp:setProperty>
  4. </jsp:useBean>
  5.  
  6. <oci:xmlxslt xsltLocation="/viewEmployee.xslt">
  7. <employee>
  8. <firstName><jsp:getProperty name="empBean"
  9. property="firstName"></jsp:getProperty></firstName>
  10. <lastName><jsp:getProperty name="empBean"
  11. property="lastName"></jsp:getProperty></lastName>
  12. <function><jsp:getProperty name="empBean"
  13. property="function"></jsp:getProperty></function>
  14. </employee>
  15. </oci:xmlxslt>
  16.  

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 that 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 that implement the previously mentioned interfaces. In typical Java style, these are helper classes that 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:

  1. import java.io.*;
  2. import javax.servlet.*;
  3. import javax.servlet.jsp.*;
  4. import javax.servlet.jsp.tagext.*;
  5. import org.apache.xalan.xslt.*;
  6.  
  7. /**
  8.  * A custom action which allows the content of a tag, which contains
  9.  * well-formed XML, to be converted to HTML using an XSLT stylesheet.
  10.  */
  11. public class XmlXsltTag extends BodyTagSupport {
  12. private String xsltLocation = "";
  13.  
  14. public int doAfterBody() throws JspException {
  15. try {
  16. // the content of the custom tag contains the XML source
  17. XSLTInputSource xmlSource = new XSLTInputSource(
  18. bodyContent.getReader());
  19.  
  20. // locate the XSLT stylesheet
  21. ServletContext sc = pageContext.getServletContext();
  22. XSLTInputSource stylesheet = new XSLTInputSource(
  23. sc.getResourceAsStream(xsltLocation));
  24.  
  25. // prepare to write the resulting HTML back to the browser
  26. JspWriter out = getPreviousOut();
  27. XSLTResultTarget resultTree = new XSLTResultTarget(out);
  28.  
  29. XSLTProcessor processor = XSLTProcessorFactory.getProcessor();
  30. processor.process(xmlSource, stylesheet, resultTree);
  31.  
  32. // inform JSP that it does not need to continue processing
  33. // the body of this custom tag
  34. return Tag.SKIP_BODY;
  35. } catch (org.xml.sax.SAXException saxEx) {
  36. throw new JspException("SAXException: " + saxEx.getMessage());
  37. }
  38. }
  39.  
  40. /**
  41.   * A setter method for the "xsltLocation" attribute
  42.   */
  43. public void setXsltLocation(String xsltLocation) {
  44. this.xsltLocation = xsltLocation;
  45. }
  46.  
  47. /**
  48.   * A getter method for the "xsltLocation" attribute
  49.   */
  50. public String getXsltLocation() {
  51. return this.xsltLocation;
  52. }
  53.  
  54. /**
  55.   * Reset the state of this object to default values in case
  56.   * JSP reuses the instance.
  57.   */
  58. public void release() {
  59. super.release();
  60. this.xsltLocation = "";
  61. }
  62. }

TLD File

The Tag Library Descriptor (TLD) is an XML file that 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 that 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 that 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.

Figure 2 shows how all of these configuration files and aliases fit together.

Figure 2

Diagram

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 excellent coverage of the tag extension mechanism. All features are covered in detail, with plenty of examples.

The Code

Download the code.

The requirements are as follows:



Software Engineering Tech Trends (SETT) is a monthly newsletter featuring emerging trends in software engineering.

Check out our most popular articles!

secret