Developing, Applying and Optimizing XSLT with Java Servlets
The missing link at this point is the servlet framework, which has
the following design.
 |
Figure 3: Servlet and XSLT architecture. |
This may seem overwhelming at first glance, but it's about
everything that is needed for a basic XSLT driven web site. The
entire design is very modular, so different programmers can work on
different pieces in parallel.
First of all, a single servlet is used rather than many. This
means that you only have one point of entry into the application,
making security, logging, and deployment easier. Since a single
servlet is responsible for the entire application, classes called
RequestHandler are used for validation logic. All the servlet does is
analyze the request to figure out which RequestHandler subclass to
invoke. This keeps the servlet small, even if your application has
hundreds of pages.
There are two basic approaches to locating request handlers. You
can either add an additional parameter to the HTTP request or add
extra path information. For example, this URL could invoke the
SubmitCustomer request handler:
http://hostname/webapp/xsltservlet?requestHandler=SubmitCustomer
With extra path information, the URL looks a little cleaner:
http://hostname/webapp/xsltservlet/SubmitCustomer
In either approach, your servlet will extract the text
"SubmitCustomer" and convert that into a class name for the request
handler. This can be accomplished via reflection or via a lookup
table. In either case, once the object is located, it is then
responsible for the remainder of this request.
The RequestHandler object may then execute methods on EJB
components that return data objects back to the web tier. These data
objects are converted to XML, which is then passed on to Apache's
Xalan or some other XSLT processor. The output from the XSLT
processor is finally delivered to the client browser.
Optimization techniques
The primary disadvantage of the XSLT approach may be runtime
performance. Every request to the servlet requires an XSLT
transformation. For most applications, performance is fast enough; a
few optimization techniques can improve the situation where maximum
throughput is required. First of all, the XSLT stylesheets are just
static XML files. These can be loaded into memory once and reused
over and over again. This substantially improves performance because
the XML only has to be parsed once.
The second major improvement is to use the Document Object Model
(DOM) for your data objects, instead of converting those to XML text
files first. For example, the following code takes the JDOM output
from the CreditInfo class and converts it to DOM, without first
writing it to a text XML file.
Example 6: Converting JDOM to DOM
DOMOutputter domOutputter = new DOMOutputter();
org.w3c.dom.Document domDoc = domOutputter.output(jdomDoc);
The domDoc object can then be passed to Xalan directly, which
should be much faster than parsing in the raw XML text from a file or
input stream. The following example is a simple test servlet that
creates some XML using JDOM, then applying an XSLT stylesheet. The
stylesheet is parsed once and then cached in memory, and the JDOM is
converted into a DOM tree that is passed to Xalan directly. Comments
in the code explain each step.
Example 7: A Servlet Example
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.xalan.xslt.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;
public class JDomServlet extends HttpServlet {
// reuse the same processor over and over
private XSLTProcessor processor = XSLTProcessorFactory.getProcessor(
new org.apache.xalan.xpath.xdom.XercesLiaison());
// initialize the Servlet. This code is executed once.
public void init(ServletConfig config) throws ServletException {
super.init(config);
ServletContext context = config.getServletContext();
try {
// read the XSLT stylesheet and cache it for future reuse
InputStream xsltStream = context.getResourceAsStream(
"/WEB-INF/viewCreditInfo.xslt");
StylesheetRoot parsedStylesheet = processor.processStylesheet(
new XSLTInputSource(xsltStream));
processor.setStylesheet(parsedStylesheet);
} catch (Exception ex) {
throw new UnavailableException(ex.toString());
}
}
// handle a single request from the client
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {
try {
response.setContentType("text/html");
// in a real app, the CreditInfo object would be retrieved
// from an EJB component
CreditInfo ci = new CreditInfo("John Q. Public",
"Visa", "111-222-333", "05/2000");
// convert the JDOM into DOM
Document jdomDoc = ci.getDocument();
org.w3c.dom.Document domDoc =
new DOMOutputter().output(jdomDoc);
// transform the XML into HTML
processor.process(new XSLTInputSource(domDoc),
null, // use pre-compiled stylesheet
new XSLTResultTarget(response.getWriter()));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Summary
|
Related information from XML.com
What is XSLT?
Transforming XML
Style-free XSLT Style Sheets |
The XSLT approach to web development has clear advantages over
traditional approaches. It does not lock you in to any vendor-specific
APIs or frameworks. Perhaps the biggest roadblock to widespread
acceptance of XSLT is programmer resistance. Many people have the
impression that XSLT is simply too difficult to use, although much of
this opinion is probably based on lack of experience rather than the
complexity of XSLT. The main reason for the perceived complexity of
XSLT is its syntax, which is a direct result of XML. Trying to
express a programming language as XML is challenging and can lead to
somewhat quirky syntax.
Beyond training and acceptance issues, an XML/Java/XSLT approach
has the distinct advantage that its constituent parts are clearly
segregated. From a project management perspective, this allows every
team member to work in parallel, rather than overloading the servlet
guru while the remainder of the team struggles to contribute.
Eric M. Burke
is an O'Reilly author and a principal
software engineer with Object Computing, Inc. in St.
Louis, MO.
Return to ONJava.com.