Add XML to your J2EE applications

Integrate an XML presentation layer in the J2EE layered architecture

Today's organizations' rapid moves to e-business bring new demands on defining flexible systems architectures. Systems need to be powerful, scalable, robust, and, most of all, capable of meeting new business demands. With that in mind, although more and more organizations are adopting a multitier, Java 2 Platform, Enterprise Edition (J2EE)-based application server architecture, they rely on HTML for the presentation layer. This prevents them from fully benefiting from the flexibility the distributed, multitier J2EE framework can offer. XML's Web publishing capabilities are key to solving this architectural shortfall.

This article proposes a replacement for the current HTML-based J2EE architecture presentation layer with a dynamic XML content layer. Through a case study, we'll see an XML-aware, open source application server within a fully operational end-to-end solution. At the heart of the case study resides Cocoon, a servlet from Apache that provides a pluggable Java presentation framework used to present XML content in a variety of formats, on demand.

The situation

J2EE defines a standard for developing multitier enterprise applications. J2EE simplifies enterprise applications by basing them on standardized, modular components, by providing a complete set of services (persistence, security, transactions, and so on) to those components, and by handling many details of application behavior declaratively, without complex programming. However, the architecture's presentation layer is primarily HTML-based, thus limiting the target audience largely to Web browsers. Tomorrow's audience will be much broader, what with a variety of new devices about to revolutionize how we send and receive information. As such, it's imperative to decouple content from presentation logic and become independent of our intended audience's devices. XML is the solution.

XML's Web publishing capabilities are possible using XSLT to transform XML documents into other textual documents. These target documents are often XML-based languages themselves (with HTML serving as a notable exception as it is based on SGML). As a metalanguage, XML can also produce other Web languages such as:

  • XHTML (for Web browsers, WebTV, and soon WAP devices)
  • WML (a language for describing two-dimensional graphics in XML)
  • SVG
  • MathML
  • VoxML (for voice)

XSLT can transform an XML document into any one of these target languages. Once we've expressed the solution in terms of XML, we can leverage it using XML's sister technologies to produce powerful, media-aware Web application that will remain invariant to target device changes.

Case study

The case study develops a software application to automate a car rental company's various processes -- reserving, renting, and returning a car. Our objectives: analyze, design, and implement the car rental agency system and build a scalable system capable of targeting multiple end user devices (Web browsers, WAP -- Wireless Application Protocol -- phones, Web TV, and so on).

For simplicity's sake, we'll implement just one use case: reserve car. Other use cases such as modify/cancel reservation, return/rent car, or maintain car could be similarly implemented.

Under the reserve car use case, the customer first calls the reservation desk to make a rental reservation. The rental reservation agent (RRA) takes the customer's name and queries the system for a match. If the customer is new, the RRA takes the customer's information and enters it into the system.

Then the RRA requests information regarding the reservation -- start date, duration of reservation, and the type of car required from the customer. Once entered into the system, the RRA checks to see if the customer's requested car type is available for the required time period. Keep in mind that other auxiliary requirements for additional information on reservation, overbooking, and vehicle availability could be added later.

After giving the customer a reservation confirmation number for future communication, the RRA calculates the amount chargeable to the customer for the terms of the reservation so that the customer knows what the rental cost will be, up front. At any point during the conversation, the customer may choose to terminate the interaction. In such a case, the reservation is canceled, but the customer information is kept should the same customer call again.

Set up the container environment

The project employs two open source containers: an EJB (Enterprise JavaBeans) container called jBoss and the Tomcat servlet container from Apache. Tomcat includes the Cocoon servlet to make it XML aware. The instructions for setting up Apache, Tomcat, and Cocoon can be found at the Cocoon Website with install cases for Unix and Windows 2000/NT. jBoss now comes with Tomcat embedded in it and can be obtained from the jBoss Website (for both sites, see Resources).

The servlet container: Tomcat enhanced with Cocoon

We'll employ Tomcat as the servlet container for this project. Tomcat, developed by the Apache Software Foundation, serves as the official reference implementation for the Java Servlet 2.2 and JavaServer Pages (JSP) 1.1 technologies. This article uses the stable Tomcat 3.2. Tomcat 4.0 (based on Servlet 2.3 and JSP 1.2 APIs) is currently in development.

Since it is based on the Servlet 2.2 API, deployment occurs with a war file -- a Web archive file (similar to a zip or jar file) used to bundle together JSP pages, associated JavaBean classes, servlets, XML files, images, and XSLT files. Since Tomcat coupled with jBoss is in essence a bare-bones application server, it makes sense, when they run on the same machine, to run them in the same JVM, which can speed up the response time by a factor of 30.

Cocoon, a 100% pure Java publishing framework also developed by Apache, relies on new W3C technologies (such as DOM, XML, and XSL) to provide Web content. Even though Cocoon is just a servlet deployed inside of Tomcat making the servlet container XML aware, it represents the backbone of our project. Cocoon allows the clear separation of content and style using the XML/XSLT paradigm. (For a clear introductory-level overview of Cocoon, see Resources.)

The EJB Container: jBoss

jBoss, an open source EJB (1.1 compliant with some 2.0 support) application server, incorporates most of the features found in a high-end application server. Because jBoss employs hot deployment for EJB jar files, deployment is as easy as dropping an EJB jar file into a deployment directory. jBoss also leverages Java 1.3's dynamic proxies features to provide dynamic compilation of subs and skeletons. Further, though not available yet, clustering capabilities using JINI technologies will soon be included.

For our project, we'll use jBoss 2.0 (with Tomcat embedded). Version 2.0 includes integration with JMS (Java Messaging Service) using SpyderMQ. JAWS (Just Another Web Storage) delivers container managed persistence for entity beans, while Minerva manages pools of database connections.

The layered architecture

The J2EE layered architecture, illustrated in Figure 1, can minimize the cost of evolving an application's functionality and updating its implementation technology. These layers can be broadly categorized as the presentation layer, application layer, service layer, domain layer, and persistence layer.

Figure 1. J2EE's layered architecture. Click on thumbnail to view full-size image. (10 KB)

Presentation layer

For our purposes, we'll focus our attention on the presentation layer, which is confined in the J2EE architecture to HTML/JSP with JavaScript for client-side validation, which therefore assumes a Web browser target device. As noted earlier, we'll use an XML solution with multiarchitecture devices as the intended targets. Once the presentation logic has been separated from the data, the rich arrangement of presentation can then be realized by using XSLT for text (HTML and XHTML), XSLFO (not a recommendation yet) for binary (PDF), and SVG for graphics.

Our presentation layer has no HTML or JSP presentation files associated with it. Instead, it uses flat XML files with other XML files dynamically created on the fly by the application layer. Then, depending on the querying device, an XSLT file delivers the presentation. The publishing engine will determine the type of the querying device and set the required XSLT file accordingly. Thus we'll separate presentation from content and clearly define the division of responsibilities.

In terms of the model-view-controller (MVC) patterns, the XML document acts as the model, the JSP in the application layer serves as the controller, and the XSLT file is the view. Then, by changing only the XSLT file, different views can be realized.

The application layer

The reserve car use case can be broken down into three areas:

  • Add customer
  • Update customer
  • Make reservation

A controller JavaServer Page -- reserve.jsp -- defines the application layer and delegates responsibility to JavaBeans. Note: in this role, the JSP serves purely as a shorthand servlet notation and contains no presentation information. Here's reserve.jsp's code:

// Reserve.jsp page
<jsp:useBean id="customer" scope="request"
<jsp:useBean id="reservation" scope="request"class=
   if( request.getParameter("btnReset") != null ) {
      session = request.getSession();
   } %>
<% String client = (String)session.getAttribute("USER"); %>
// Checks if the client exists
<% if(client == null){ %>
   // Checks if the name field has been filled in
   // If the name field is null, then the user is presented with a login file
   <% if (request.getParameter("name") == null)
   { %>
       <jsp:forward page="login.xml" />
    // if the address field is null, then the user is presented
    // with a customer details form
    <% } else if (request.getParameter("address") == null)
       { %>
           <jsp:setProperty name="customer" property="*"/>
         <% customer.getCustomer(); %>
         <% String customerXML = customer.toXML(); %>
         <% session.setAttribute("CURRENTDOC", customerXML); %>
         <jsp:forward page="/servlet/com.valtech.bootcamp.
           carRental.web.cocoon.CocoonFromServlet" />
      <% } else { %>
   // The user has completed the form, and the customer's
   // data has been persisted
   // A String object is also saved to the session context
   // to show that the customer has been
   // validated for this session
         <jsp:setProperty name="customer" property="*"/>
         <% customer.setCustomer(); %>
         <% session.setAttribute("USER", "true"); %>
         <jsp:forward page="reserve.jsp" />
       <% } %>
<% } else { %>
    // Checks if the stateDate field has been filled in
    // If the field is null, the user is presented with a
    // reservation page with the name of the customer filled in
   <% if (request.getParameter("startDate") == null) { %>
      <% reservation.setCustomerName(customer.getName()); %>
      <% String reservationXML = reservation.toXML(); %>
      <% session.setAttribute("CURRENTDOC", reservationXML); %>
      <jsp:forward page="/servlet/com.valtech.bootcamp.carRental.
         web.cocoon.CocoonFromServlet" />
       <!-- <jsp:forward page="reservation.xml" /> -->
   // If the startDate field has been filled in, the full reservation
   // details are displayed to the customer
   <% } else { %>
        <jsp:setProperty name="reservation" property="*"/>
        <% reservation.setReservation(); %>
      <% String reservationXML = reservation.toXML(); %>
      <% session.setAttribute("CURRENTDOC", reservationXML); %>
      <jsp:forward page="/servlet/com.valtech.bootcamp.carRental.web.
         cocoon.CocoonFromServlet" />
   <% } %>
<% } %>

As seen in the preceding code (see the useBean tags at the start of the code) the controller JavaServer Page uses two JavaBeans: a Customer bean and a Reservationbean. This simplifies the JSP by abstracting out any complex remote method invocation and delegating that responsibility to the JavaBeans. Thus the JSP now concerns itself only with simple logic. It then routes control to various other pages depending on that logic. This also makes testing of the JSP much easier as a test can now be written for each bean and tested without the added complexity of having to deploy the bean in a servlet container.

As a further responsibility, the bean produces an XML representation of itself. Each bean possesses a toXML()method that returns an xmlised string of the data represented in the bean. Presently, these functions do only a simple string concatenation of the bean's attributes, but this could be done with a more complex DOM or JDOM representation.

1 2 3 4 Page 1
Page 1 of 4