ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Developing, Applying and Optimizing XSLT with Java Servlets
Pages: 1, 2, 3

Problems with typical servlet approaches

Separation of data, presentation, and programming logic has always been an issue for servlet developers. The first generation of servlets were deployed as replacements for CGI programs, and typically contained code that looked like



Example 2: Tedious HTML Generation Code

PrintWriter pw = response.getWriter();
pw.println("<html>");
pw.println("<head><title>Home Page</title></head>");
pw.println("<html>");
pw.println("<h1>Welcome to our web site</h1>");
...remaining tedious code omitted!

This approach is tedious, error prone, and hard to maintain. It completely locks out non-programmers from web authoring, and it requires significant effort to change the look of a web site generated this way. Although you generally will write the code in modular, reusable fragments of HTML, the approach still requires source code changes for any new requirements.

Java Server Pages (JSP) provides a solution to this problem. Unfortunately, JSP only reverses the problem. Instead of embedding HTML code into servlets, you typically end up embedding Java code into your HTML pages. JSP custom tags do allow you to remove all Java code in theory, but this is not without the difficulty of first creating the tags or else finding an existing tag library that meets your needs. The following example shows how JSP custom tags are used within a JSP page.

Example 3: JSP Using Custom Tags

<%@ taglib uri="/my_taglib" prefix="abc" %>
<html>
<head>
<title>JSP Tag Library Demonstration</title>
</head>
<body>
  <abc:standardHeader/>
  <abc:companyLogo/>

  <h1>Recent Announcements</h1>
  <abc:announcements filter="recent"/>

  <h1>Job Openings</h1>
  <abc:jobOpenings department="hr"/>
  <abc:standardFooter/>
</body>
</html>

Even with custom tags, it is virtually impossible to remove all Java code in a pure JSP solution. Specifically, the pure JSP approach breaks down when complex HTML forms are submitted and the JSP has to perform validation. For this reason, most modern web architectures stress a hybrid solution, in which servlets are responsible for intercepting requests and validating form data, and JSP is used for sending the response back to the browser.

Hybrid servlet and JSP Approach.

Figure 2: Hybrid servlet and JSP approach.

As Figure 2 illustrates, a class called RequestDispatcher is responsible for coordinating between the servlet and JSP. This class is part of the javax.servlet package; it can either forward the request as shown above or include the output of another web resource into the current page.

This approach is sometimes referred to as "Model 2" and is very easy to implement. Its primary limitations manifest themselves when multiple client browser types must be supported or when Wireless Markup Language clients are desired. Additionally, providing a raw XML data feed to a non-browser client is increasingly popular, and JSP does little to address that need.

The XSLT + servlet approach

The design process for an XSLT-backed web site can be driven from the HTML or the database. When your requirements dictate a certain HTML page layout, the first step is to create HTML prototypes and then analyze which pieces of the HTML are dynamic and which are static. The static content will become part of one or more XSLT stylesheets, while the dynamic content must come from an XML data source. For example, an application that prompts the user to enter his or her credit card information could use the following XML document.

Example 4: XML Document

<?xml version="1.0"?>
<creditInfo>
  <name>John Q. Public</name>
  <type>Visa</type>
  <number>111-222-333</number>
  <expires>05/2000</expires>
</creditInfo>

The web page will obviously contain a lot more information such as text fields, graphics, captions for each field, and tables for layout. Since that presentation data is the same for every user, however, it can easily be placed in a stylesheet. The stylesheet shown in Example 1 was written for this document.

Related:

Style-free XSLT Style Sheets - Building web sites with XSLT sometimes raises architectural issues. This article presents a pattern for maintaining a clear separation between style, logic, and content in XSLT-produced websites. [From XML.com]

If your design is dictated by an existing database, then instead of creating HTML prototypes, you generally start with the XML specification. In either approach, you will probably find yourself iterating through several potential schemas before finalizing your XML. One thing that can easily be overlooked is that XML must sometimes contain items that are not pure data. For instance, if your web site contains a navigation bar along the top of each page, then the current page will typically be highlighted somehow. It may simulate a folder tab, where the current page is the active tab. In this situation, the XML must specify which tab is current, although that data would certainly not reside in your database. The ultimate solution is to extract "pure" data from the database and add on any GUI specific items as you are generating the XML.

Once the XML has been clearly defined, perhaps with an associated Document Type Definition (DTD) or schema for validation, the XSLT stylesheets that create the HTML can be written. This is another advantage of this architecture: the database does not need to be present in order to begin working on this task. The XSLT can be developed completely independently of any servlet or database code by using static XML files. An XSLT processor can be invoked from the command line for testing, or integrated tools like XML Spy can be used to speed up the process.

While some of your team is developing the XSLT stylesheets, work can begin on two other fronts. First, a basic servlet framework needs to be implemented. Although you may want to look into existing XSLT frameworks, the model is so simple that it works well enough to write your own servlet code.

Second, someone else can be writing JDOM code to generate the XML dynamically. This may involve creating some sort of abstraction to a relational database, or perhaps some interfaces to EJB components in a multi-tier application. In either case, the first step is to write Java classes that know how to convert a data object, such as CreditInfo, to the XML representation you defined earlier. In the example shown below, the CreditInfo class uses JDOM to convert itself to the <creditInfo> document shown above. In case you are wondering, JDOM is an open source Java API for dealing with XML. It is available at jdom.org.

Example 5: XML Generation Using JDOM

import java.io.*;
import org.jdom.*;
import org.jdom.output.*;

/**
 * Example of an object that knows how to represent itself as
 * XML using JDOM.
 *
 * @author Eric M. Burke
 */
public class CreditInfo implements Serializable {
    private String name;
    private String type;
    private String number;
    private String expires;

    // transient fields are not serialized.  This prevents the potential
    // overhead of sending too much data between an EJB and the web tier
    private transient Document doc = null;
    private transient Element elem = null;

    /**
     * Construct a new data object.
     */
    public CreditInfo(String name, String type, String number,
            String expires) {
        this.name = name;
        this.type = type;
        this.number = number;
        this.expires = expires;
    }

    /**
     * @return the contents of this object as an XML document.
     */
   public Document getDocument() {
       if (this.doc == null) {
           this.doc = new Document(getElement());
        }
        return this.doc;
    }

    /**

* This method makes it possible to easily embed the output from * this data object into some other larger XML document. * * @return the contents of this object as an Element, which is just * the root element without the XML declaration. */ public Element getElement() { if (this.elem == null) { this.elem = new Element("creditInfo"); this.elem.addContent(new Element("name").setText(this.name)) .addContent(new Element("type").setText(this.type)) .addContent(new Element("number").setText(this.number)) .addContent(new Element("expires").setText(this.expires)); } return this.elem; } /** * A simple test program. */ public static void main(String[] args) throws IOException { // create an object CreditInfo ci = new CreditInfo("John Q. Public", "Visa", "111-222-333", "05/2000"); // convert to XML, then format with two space indent Document doc = ci.getDocument(); new XMLOutputter(" ", true).output(doc, System.out); } }

You may have heard of Document Object Model (DOM), the standard XML object model from the W3C. If you have worked with DOM, you will immediately see from the example above that JDOM is significantly easier for Java programmers to work with. This is actually the intent of JDOM. DOM is specified using CORBA IDL, so it can be mapped to many different languages. Unfortunately, the Java mapping does not take advantage of Java's unique language capabilities, resulting in a lot more work for programmers.

Pages: 1, 2, 3

Next Pagearrow