Chapter 9. Templating

Introduction

Systems designed without clear separation between presentation and application logic quickly become chores to maintain. Trivial look-and-feel updates in such applications take days or weeks, and trying to extend such a coupled architecture can introduce unmanageable risks and code that is impossible to unit test. To minimize the possibility of creating such disasters, avoid coupling presentation and application logic through the use of a good templating engine. Maintain clear separation between presentation and application logic from the beginning—be orthogonal. Don’t print out HTML, XML, or SQL from Java code, use a templating engine.

The simplest example of templating is Java’s MessageFormat. A simple message, such as Hello {0}, I speak {1}, can be parameterized using the MessageFormat class. A more complex templating example is found in applications that use Jakarta Velocity or FreeMarker to avoid mixing Java with HTML or textual output. Throughout this spectrum of complexity, the concept of templating remains the same; a template with references to variables is merged with a context containing these variables. There are many ways to decouple the rigors of logic from the prettiness of presentation, and after reading this chapter, you will have a range of options for different situations.

This chapter touches upon Jakarta Velocity, Jakarta Commons JEXL, and a technology outside of the Apache Software Foundation named FreeMarker. Templating engines are frequently used in web application, and this chapter ends with instructions for integrating these engines into a J2EE web application. Separating HTML or textual content into a separate file allows you to give graphic designers and business users a larger role in customizing and creating content for the enduser. With a templating engine, you can dramatically reduce the time and effort it takes to make simple changes. But, by far, the largest benefit of a templating engine is that it allows programmers to do more programming and graphic designers to do more designing by reducing needless coupling of presentation markup and compiled application logic.

Common Templating Problems in Applications

Server-side Java has won a fair amount of attention over the past five years, but developers seldom consider using templating engines when writing a standalone Java application. Consider the following code, which prints a formatted report for a bank customer:

System.out.println( "******************************" );
System.out.println( "******* BANK STATEMENT *******" );
System.out.println( "******************************" );
Account[] accounts = AccountUtil.getAccounts("1232");
double total = 0.0;
for( int i = 0; i < accounts.length; i++ ) {
    System.out.println( "Account: " + 
        accounts[i].getBalance( ) );
    total += accounts[i].getBalance( ); 
}
System.out.println( "Total: " + total );
System.out.println( "******************************" );

In this example, textual content is mixed with Java code, and a programmer must be involved in any change to the look and feel of the report. If this report were generated using an external template, a nonprogrammer could be trained to change the report, or the customers could customize the output of this program by modifying a template with straightforward syntax.

Consider another common problem: generating an XML document. There are seemingly thousands of ways to create an XML document: using DOM or JDOM to create a Document object, serializing an object with Jakarta Commons Betwixt, and using Exolab’s Castor are a few of these possibilities. Some of these techniques are explained in Chapter 6, but here is an example of how not to generate an XML document:

System.out.println("<?xml version="1.0"?>");
System.out.println("<Config>");
System.out.println("<Property name="" + name + ""
" +
                   "value="" + value + ""/>");
System.out.println("</Config>");

Avoid this practice at all costs. Here are a few red flags from the previous two examples:

Mixed languages

Nesting an XML document into a Java class by way of printing out String literals is unreadable. When you need to mentally decode heavily escaped XML nested in Java, you are asking yourself to do too much at once. You will also end up with mixed context, an XML element starting within a pair of parentheses, and ending in another. In this fugue of forward and back slashes, one misplaced slash produces an invalid XML document, or one overlooked NullPointerException causes a catastrophe. You are asking your brain to compile two strands of code with intertwined and overlapping syntax. While your compiler might not complain, your system will be difficult to maintain. Code that is difficult to comprehend is even more difficult to maintain.

Escaped characters in compiled code

Escaping characters in String literals quickly becomes an annoyance, especially if the strings to be encoded contain back slashes and double quotes. I accept that the String c: emplah.txt, must be written as c:\temp\blah.txt, but I don’t enjoy doing it. How confusing is a literal "c:\temp\“? Avoid this entirely by using a templating engine or externalizing strings in properties files.

Mixing presentation with conditional or iterative logic

A previous example printed each account balance in a for loop. A common trick in JSP is to create a while loop with JSP scriptlets, surrounding the code to be executed with <% while( i < 4 ) { %> and <% } %>. Templating languages such as Velocity or even JSP 2.0 with JSTL support conditional and iterative operations without asking you to mix languages.

There are other opportunities for using a template in an application. These include code generation, creating SQL scripts, and interacting with an interpreted language via generated scripts. The list continues, and it proves that templating isn’t just for making web pages.

Templating in Web Applications

Examine the JSP code below (the variable names have been changed to protect the innocent). Take this code and multiply it by 100 or 200 pages. Now, what happens when you want to move from PostgreSQL to Oracle? Do you do a global search and replace on the driver class name and the JDBC URL? Or, even worse, what happens when someone asks you to translate the entire site to Chinese in two weeks? It would be easier to learn Chinese in two weeks than it would be to internationalize this code. The offending JSP is:

<% ResultSet rs;
    try {
      Class.forName( "org.postgresql.Driver" );
      String dbURL = "jdbc:postgresql://192.168.0.1/dbname";
      Connection dbCon = 
            DriverManager.getConnection( dbURL, "system", "");

        PreparedStatement ps = 
            dbCon.prepareStatement( "select * from Offer " +
                                  "where id = ?" );
      ps.setString( 1, request.getAttribute("id") );
      rs = ps.executeQuery( );
        rs.next( );
    } catch( Exception e ) {
        %><%= Something bad happened, Call Jack (800) 232-2233 %>
<% } %>

<jsp:include page="header.html" />

Hello <%= rs.getString("name") %>,

I would like to inform you of a good offer.
<%= rs.getString("offerText") %> 

There are a few things I would like to tell you.
<ul>
  <% Thing[] things = OfferUtil.getThings( rs.getString("id") );
     for( int i = 0; i < things.length; i++ ) { %>
     <li><%= things[i].getText( )%></li> 
  <% } %>
</ul>    

<jsp:include page="footer.html" />

Tip

This is real code from a real system, and it was written by a whole team of programmers who didn’t find anything terribly wrong with this style. If you were raised on JSP like this, you might not recognize some of the problems. What is wrong with the previous example? Four different “languages” are combined in one file (Java, SQL, HTML, and JSP); the page starts off with JSP scriptlets, then the example contains Java code that prints out HTML and generates SQL statements. Lastly, this particular JSP page forgets to close the connection it created to the database—something that could easily create a resource leak under a heavy load. Make it simpler, use a templating engine (or upgrade to JSP 2.0) and never write a line of Java in a JSP again.

Velocity, JEXL, and FreeMarker are remedies for the coupling issues demonstrated in the previous examples. Each of these tools can be integrated into any application in a matter of minutes. In this chapter, you will learn techniques for separating presentation logic from behavioral (or business) logic. At the end of the chapter, I will briefly explain how you can integrate all of these utilities into a J2EE web application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.151.164