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)
| 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. |
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.
<jsp:include .../>. Custom actions
are new actions which are created by programmers, extending the capabilities
of JSP. Two interfaces are provided for the creation of custom actions:
Tag and BodyTag.
|
| Fig 1 - Graphical Depiction of Terms |
<%@ 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.
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 = "";
}
}
<%@ 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:
"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.