Boost Struts with XSLT and XML

An introduction to Model 2X

Since the Java Servlet API's inception, developers have used diverse technologies to develop Web applications in Java. Recently, developers have started to recognize the merits of Model 2, a scheme derived from the Model-View-Controller (MVC) paradigm. Model 2's benefits include an improved separation of the application logic and presentation layers. Struts, built on top of Model 2, additionally offers Java developers a generic controller servlet, centralized configuration, resource management, and error handling.

In this article, we introduce Model 2X, a scheme that further enhances Struts. By replacing JSPs (JavaServer Pages) with XML and XSLT (Extensible Stylesheet Language Transformations), Model 2X offers an even better approach to separating logic and presentation. We start with an introduction to Model 1 and Model 2, describe how Struts implements MVC, and finally show how XML and XSLT can be used to improve the existing models.

Model 1

Understanding Model 1 is crucial to understanding the subsequent architectures we discuss in this article. Model 1's cornerstone is the JSP file, which extracts parameters from an HTTP request, calls the required business logic, handles the HTTP session, and then generates HTML.

A complete Model 1 application is composed of a collection of JSP files, mostly independent of each other, and, optionally, a collection of support classes and other components. Earlier technologies, such as ASPs (Active Server Pages) and PHP (hypertext preprocessor), used this same model.

Model 1's major, and possibly only, benefit: simplicity. However, Model 1 encourages the developer to mix business logic and presentation logic, a significant drawback. While this model is appropriate for creating small applications, complex application development with Model 1 can become difficult to manage.

Model 2, MVC, and Struts/JSP

Object-oriented paradigms in the form of the MVC architecture rescued the JSP and servlet world by defining Model 2. Figure 1 illustrates MVC's three parts and their implementation in Struts/JSP.

Figure 1. Model 2

Controller

As Figure 1illustrates, the Struts' main component is a generic controller servlet. The Struts controller provides the initial entry point for all HTTP requests routed to Struts. It interprets and dispatches all requests to individual actions implemented by the developer as subclasses of the Struts Action class. It also automatically fills out form beans from request parameters. Individual actions implement core business logic by, for example, making EJB (Enterprise JavaBean) calls, and access the model through JavaBeans. An XML file that maps request URIs to actions and form classes configures the controller servlet.

Model

The model takes the form of one or several JavaBeans. Those beans fall into three categories:

  • Form beans hold either the data the user entered in HTML forms or, more generally, any attribute passed either on the URL or in a POST. For instance, a form bean for a login page could have two properties: login and password. Form beans extend the Struts ActionForm class.
  • Request beans hold information needed to generate the HTML page. In the case of a bank account statement page, a request bean would have properties with information about the account as well as a transaction bean collection detailing the most recent transactions to display.
  • Session beans hold session information that persists between two HTTP requests by the same user.

View

The controller servlet forwards a request to a JSP implementing the view. The JSP can access the form, request, and session beans and outputs a result document (usually an HTML document) sent to the client. Struts provides four JSP tag libraries:

  • HTML: Helps create HTML tags, particularly by filling out HTML forms with data from the model.
  • Bean: Manipulates beans.
  • Logic: Implements logic constructs based on bean values.
  • Template: Handles page templates.

With the Struts tag libraries, you can usually avoid using any Java code in the view.

Struts/JSP drawbacks

While the Struts/JSP approach features many advantages over other models, it exhibits several drawbacks:

  • As in Model 1's case, nothing prevents a developer from embedding application logic into the JSP. Experience shows that many developers actually fall into that trap, often to perform a quick fix. This can lead to applications that are hard to understand and maintain.
  • The JSP syntax is not XML compliant and therefore fails to guarantee that resulting XML or HTML documents will be well formed.
  • The developer must learn new APIs -- the Struts tag libraries. Experience shows that gaining an understanding of the Struts tag libraries, particularly the bean and HTML libraries, can take a long time.
  • You can't implement a real processing pipeline in the view with JSP. Only basic includes and forwards are possible, effectively limiting the view's flexibility. For example, separating layout and style proves difficult.
  • With JSPs, you must recompile after every change, which can be time consuming. Just ask any JSP developer waiting for page compilation after every mouse click.

The solution to these problems must:

  • Restrict the visibility in the view to the model and some well-defined context information, such as resources.
  • Enforce well-formed XML and HTML.
  • Leverage existing languages or APIs.
  • Ease the separation of different view aspects, like layout and style.
  • Allow for a faster development cycle.

As detailed, the Model 2 technology currently features many issues that must be addressed. We believe the lightweight framework detailed below, based on an unmodified version of Struts and XSLT, exceeds the given requirements. We call the new architecture Model 2X.

Model 2X: Architecture overview

Model 2X is the symbiosis between Struts and XSLT. Model 2X uses the Struts model (its controller servlet), but the view implementation uses XSLT and beans serialized into XML instead of JSPs.

What is XSLT?

XSLT is a functional language designed to perform transformations on XML documents. It is part of a stylesheet language for XML known as XSL. XSLT uses XPath, an expression language that accesses or refers to parts of an XML document. In addition to XML dialects such as XHTML, XSL/FO (formatting objects), or SVG (Scalable Vector Graphics), XSLT can output any text format, including HTML or CSV (comma-separated values). Also part of the XSL specification, the XSL/FO language displays elements on a page. Its main application: generating PDF documents.

Integrate XSLT with Struts

The first approach to integrating XSLT with Struts is to call an XSLT transformer from within a JSP. You do that with a tag library -- the Jakarta Project's XSL tag library, for example. You now generate XML, instead of HTML, in the JSP. Thanks to an XSLT stylesheet, the XML then transforms into HTML or other formats. However, this transformation requires changes to Struts itself.

The most common way to generate HTML forms is through the Struts HTML tag library, which is not XML compliant and therefore unusable in conjunction with XSLT. Modifying the HTML tag library to output XHTML is easy, but it still changes the existing Struts 1.0 codebase.

Furthermore, the tag library solution requires programming in four separate places: the Action class (controller), the model beans, the JSP, and the XSLT stylesheet (view). This requirement creates a labor-intensive solution. Additionally, the roles of the JSP and tag libraries are limited to converting the model beans into an XML document.

The second approach, which is our proposed Model 2X solution, automates this task, effectively removing JSPs from the equation. As Figure 2 illustrates, this design decision forms the heart of Model 2X.

Figure 2. Model 2X

As you can see in Figure 2, the first part of the Model 2X pipeline is the regular Struts pipeline. The request is sent to the Struts controller servlet, then dispatched to the appropriate business logic, an Action subclass. The controller creates an ActionForm object; the object is filled with the appropriate request parameters. The Action subclass encapsulates the business logic, fills out the beans, and then forwards the beans to the view.

That is where the Model 2X pipeline differs from regular Struts: instead of a JSP implementing the view, a servlet, XSLServlet, now implements it with an XSLT stylesheet's help. This servlet first generates an XML document from the beans and context, and calls the XSLT transformer. We detail this process below, which you can achieve without changing Struts because you can forward a request to any URL in the Struts configuration.

XML generation

The process of transforming an object into a stream is known as serialization. Since Java 1.1 introduced the java.io.Serializable interface and related APIs, Java developers have understood binary serialization well. Binary serialization transforms a Java object into a binary stream that can be sent over the network or saved into a file. In contrast, XML serialization transforms a Java object tree into a textual XML stream.

Many closed and open source software packages, such as Castor, perform XML serialization. For the Model 2X application, we used a simple custom implementation. This simple implementation assumes that all bean properties are either primitive Java types or java.util.Collection subclasses.

The custom implementation recursively introspects the form, request, and session beans, and creates a DOM (Document Object Model) tree. Concurrently, the implementation serializes the resources and Struts configuration data known as context information. Figure 3 illustrates this process.

Figure 3. XML/XSL workflow

XSLT processing

The XML stream represents a translation of the model on which the XSLT stylesheet is applied. In the Model 2X application, XSLT transformation is limited to a single stylesheet cached by XSLServlet and applied to the XML stream provided by the Struts pipeline. You can enhance this simple architecture to provide several successive transformations or more advanced configurations as seen in the Apache Cocoon framework. An XML publishing framework, Cocoon uses XML and XSLT to build server-side applications. Its pipeline-based architecture makes it easy to separate content and logic, and to interact with many different data sources. XSLT allows Cocoon to adapt its output to different device capabilities such as HTML, WAP (Wireless Application Protocol), and so on.

Figure 3 shows an XSLT pipeline example. The following section presents another example of content and layout separation.

Transformation example

Consider a Struts application with a simple form bean containing two attributes:

  public class TestForm extends ActionForm {
      private String testString;
      private List testList;
  }

The XML serialization code produces the following XML fragment, assuming testString and testList are populated respectively with My Test String and One, Two, Three. Note that the element names in the XML document are predictable, making it easy to write the stylesheet:

  <page name="TestForm">
    <request>
      <TestForm>
        <testString>My Test String</testString>
        <testList>
          <item>One</item>
          <item>Two</item>
          <item>Three</item>
        </testList>
      </TestForm>
    </request>
  </page>

This simple XSLT template transforms the serialized stream to an XHTML fragment:

  <xsl:template match="page">
     <h2>Please enter some text and submit</h2>
     <br/>
     <form name="testForm" method="get" action="result">
       <input type="text" name="testString" 
value="{request/TestForm/testString}"/>
       <br/>
       <select name="outSelect">
          <xsl:for-each select="request/TestForm/testList/item">
            <option><xsl:value-of select="."/></option>
          </xsl:for-each>
       </select>
       <br/>
       <input type="submit" value="Submit"/>
     </form>
     <hr/>
   </xsl:template>

After transformation and HTML serialization, the result will look like this:

  <h2>Please enter some text and submit</h2>
  <br>
  <form name="testForm" method="get" action="result">
    <input type="text" name="testString" value="My Test String">
    <br>
    <select name="outSelect">
      <option>One</option>
      <option>Two</option>
      <option>Three</option>
    </select>
    <br>
    <input type="submit" value="Submit">
  </form>
  <hr>

Model 2X's major benefits

In this section, we explain the benefits that Model 2X offers compared to the earlier models.

Business and presentation logic separation

The raw material used by the stylesheet is the XML stream, which is entirely defined by the model and the context. Although some XSLT transformers support extensions, letting you call Java code or other languages from within a stylesheet, use of such extensions is limited due to the additional effort required and the resulting lack of portability. This difficulty effectively removes any possible side effects during the XSLT transformation and separates the business and presentation logic.

1 2 Page
Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more