Foundations of JSP design patterns: The View Helper pattern

Learn how the View Helper pattern helps you adapt model data to an application's presentation layer

The View Helper pattern specifies that you use helpers to adapt model data to the presentation layer of an application. Typically, the presentation layer contains several JSP (JavaServer Pages) pages. These pages consist of HTML and images used to present content to the user. A problem arises, however, when these pages need to display dynamic content stored in the model. You'd probably like to avoid embedding Java code within these pages to display model data, so you need to employ some helpers to do the work for you.

Recall from the previous chapter that the controller servlet attaches the model to the request as an attribute. To get at this model from within the JSP page, you have three choices. You could embed Java code as JSP scriptlets, you could use the EL, or you could use a helper to extract the data for you. In keeping with the idea of separating presentation from business logic, it makes sense to employ several helpers to adapt the model to the presentation rather than clutter the presentation code with Java code (see Figure 1).

Figure 1. View Helper pattern

As you can imagine, helpers make it a lot easier for page designers to develop the presentation layer by replacing Java code with simple-to-use helpers. Of course, developers can accomplish this only if they publish a catalog of the helpers and describe how to use them. However, if the page designers develop their pages before the application designer is ready to give them a model for the helpers with which to work, then there's a problem. A useful technique to address this problem is to code into the helper a set of dummy data to display when no model is present. An alternate approach would be to provide a dummy model with which to work. Either way, the page designer shouldn't be held up while waiting for the developers.

Using helpers has the following advantages:

  • Presentation components are standardized, creating a consistent look and feel for the application
  • Java code is abstracted away from page designers, giving them an easy-to-use set of helpers to access the model
  • You can create helpers to display dummy data if no model exists, thus letting page designers continue development regardless of the readiness of the application
  • Helpers provide a clean separation between presentation and business data by acting as intermediaries between the two

Implementing View Helper pattern strategies

When developing helpers for JSP pages, you have two choices. You could use either JavaBeans or custom tags. Which you choose really depends on the type of data you're trying to adapt. Typically, you use JavaBeans to extract individual pieces of data, and custom tags are better suited for working with sets of data. However, it's important to point out that you can use either for both types of data.

Implementing the JavaBean helper strategy

You can implement helpers as JavaBeans within a JSP page. These helpers are typically easy to use when extracting and formatting single text items. The built-in JSP tags that enable you to work with JavaBeans are simple and intuitive to use. Using JavaBeans involves simply declaring the bean and referencing it later using the special tags as follows:

 <%-- Declare bean --%>
<jsp:useBean id="myBean" class="jspBook.util.myBean"/>
<%-- Get first name from bean --%>
Hello <jsp:getProperty name="myBean" property="firstName"/>,
welcome to Acme Products' online store!

JavaBeans can do more than simply retrieve data items from the model. They can also format specific data items, perform calculations, or generate large blocks of content. Ideally, they're suited to retrieving data items using the built-in JSP tags. If you do much more with them, then your JSP pages may begin to get cluttered with too much Java code, no matter how much you try to use the EL. In that case, you may consider encapsulating any additional behavior inside a custom tag.

Implementing the custom tag helper strategy

For more complex model adaptations, custom tags have the ability to embed Java code and perform several iterations over the data while providing the page designer with a simple tag with which to work. To use custom tags, you write a class that extends either TagSupport or BodyTagSupport. You declare this class in a tag library descriptor as shown in Listing 1.

Listing 1. An Example TLD

 <?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
web-jsptaglibrary_2_0.xsd"
   version="2.0" >
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>myTags</short-name>
<description>
   Tag library to support the examples in Chapter 8
</description>
<tag>
   <name>myTag</name>
   <tag-class>jspbook.ch08.myTag</tag-class>
   <body-content>JSP</body-content>
   <attribute>
      <name>myAttribute</name>
      <required>yes</required>
      </attribute>
</tag>
</taglib>

This tag is then referenced inside the JSP page by first declaring it with the taglib directive and then by referencing the tag as follows:

 <%@ taglib uri="/helpers" prefix="helpers" %>
<helpers:myTag myAttribute="some value">
   Body text...
</helpers:myTag>

I prefer to use custom tags for most view helpers. They give the developer more access to the servlet context and offer some performance benefits when they're pooled within the application server. Another reason I like to use custom tags is that they're intuitive for a non-Java page designer. Their format is much like standard HTML tags, which by now have become second nature to most of us. Finally, you can use custom tags—once they're developed and debugged— across JSP pages in your application. If the tags are designed to be generic enough, you can package them as a tag library, which can be reused across applications.

Implementing the model separation strategy

Whether using custom tags or JavaBeans, it's sometimes useful to provide standalone helpers that can present a set of dummy data in place of the model when no model exists. This would enable page designers to complete their work independent of the development team. To implement this strategy, the helper needs to check for the existence of a model and then uses either the real model or a static copy of the model to operate on (see Figure 2).

Figure 2. Model separation strategy

To make this work, the static model needs to be an exact replica of the real model. It's not always easy to keep these two in sync with each other. An alternate, and sometimes preferable, strategy is to have the development team build dummy data into its models so that designers can do their work as if the real model exists, also ensuring that the model they're working with is always the correct one (see Figure 3).

Figure 3. Alternate model separation strategy

Applying the View Helper pattern

The following helpers you'll build may be useful to you at some point, but at the very least they should give you some ideas of how you can apply the View Helper pattern to your own applications. The following items are implemented as custom tags and are declared in the helpers.tld file. This file is associated with the /helpers taglib URI inside the web.xml file with an entry like this:

 <taglib>
   <taglib-uri>/helpers</taglib-uri>
   <taglib-location>/WEB-INF/tlds/helpers.tld</taglib-location>
</taglib>

Formatting text

I'll begin this section with a view helper for adapting numeric values to various date and currency formats. Although it may be simple to do this directly in the model, you may have several reasons to format these values in the view instead. For instance, you may need to display the same value in various localized formats, or maybe the content will be accessed via multiple devices that require a different way to present the data.

You could encapsulate various formatting functions within a custom tag that reads the value to be formatted from its body and then formats it based on an attribute you set in the tag. Listing 2 shows how you would describe this tag in your tag library descriptor file.

Listing 2. helpers.tld

 <?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
web-jsptaglibrary_2_0.xsd"
   version="2.0" >
   <tlib-version>1.0</tlib-version>
   <jsp-version>2.0</jsp-version>
   <short-name>helperTags</short-name>
   <description>
      Tag library to support the examples in Chapter 8
   </description>
   <tag>
      <name>FormatTag</name>
      <tag-class>jspbook.ch08.FormatTag</tag-class> 
      <body-content>JSP</body-content>
      <attribute>
         <name>format</name>
         <required>yes</required>
         <rtexprvalue>true</rtexprvalue>
      </attribute>
   </tag>
</taglib>

The model for this tag could be just about anything, but, for this example, you'll create a static JavaBean containing two string objects to hold a date value and a currency value. You'll set these from your JSP page using the standard JSP setProperty tag. To accomplish this, of course, your JavaBean needs to define accessor methods for both string values. Listing 3 shows the code used to create this JavaBean.

Listing 3. FormattingModel.java

 package jspbook.ch08.beans;
import java.io.Serializable;
public class FormattingModel implements Serializable {
   private String dateValue;
   private String currencyValue;
   public FormattingModel () {}
   /* Accessor Methods */
   public void setDateValue (String _date)
   {
      this.dateValue = _date;
   }
   public String getDateValue ()
   {
      return this.dateValue;
   }
   public void setCurrencyValue (String _currency)
   {
   this.currencyValue = _currency;
   }
   
   public String getCurrencyValue ()
   {
      return this.currencyValue;
   }
}

The tag itself is a simple body tag extending the BodyTagSupport class. All the actual formatting code is inside the formatValue() method. This method is called from within the doAfterBody() method once the value has been retrieved. The result of the formatValue() method is written back to the page in place of the tag. You can format dates and currencies using classes found in the java.text package. Specifically, you can use the SimpleDateFormat and DecimalFormat classes.

The tag handler also provides a Locale object, along with an appropriate set method, to accommodate specific localization of the content. Because this tag is responsible for formatting date and currency values, it may be necessary to pass different locales to the formatting operations. Take a look at the code in Listing 4, paying special attention to the formatValue() method.

Listing 4. FormatTag.java

 package jspbook.ch08;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.BodyContent;
import java.io.IOException;
import java.util.Locale;
import java.util.Calendar;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.NumberFormat;
import java.text.DecimalFormat;
public class FormatTag extends BodyTagSupport {
   /* Locale object for internationalization of content */
   private Locale locale;
   /* Tag Attributes */
   protected String format;
   /* Static Constants */
   private final static String DATE_LONG = "date";
   private final static String NUMERIC_DECIMAL = "decimal";
   private final static String NUMERIC_ROUNDED = "rounded";
   private final static String NUMERIC_CURRENCY = "currency";
   public FormatTag() {
      locale = Locale.getDefault();
   }
   public void setLocale(Locale locale) {
      this.locale = locale;
   }
   /* Process Tag Body */
   public int doAfterBody() throws JspTagException {
      try {
         BodyContent body = getBodyContent();
         JspWriter out = body.getEnclosingWriter();
         /* Get Input Value */
         String textValue = body.getString().trim();
         /* Output Formatted Value */
         out.println(formatValue(textValue));
      }
      catch (IOException e) {
         throw new JspTagException(e.toString());
      }
      return SKIP_BODY;
   }
   /* Process End Tag */
   public int doEndTag() throws JspTagException {
      return EVAL_PAGE;
   }
   private String formatValue (String _input)
   {
      String formattedValue = "";
      try {
         if(format.equals(DATE_LONG)) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(DateFormat.getDateInstance(
               DateFormat.SHORT).parse(_input));
            SimpleDateFormat df = new SimpleDateFormat("EEE, MMM d, yyyy");
            formattedValue = df.format(cal.getTime());
         } else if(format.equals(NUMERIC_DECIMAL)) {
            DecimalFormat dcf = (DecimalFormat) NumberFormat.getInstance(locale);
            dcf.setMinimumFractionDigits(2);
            dcf.setMaximumFractionDigits(2);
            formattedValue = dcf.format(dcf.parse(_input));
         } else if(format.equals(NUMERIC_ROUNDED)) {
            DecimalFormat dcf = (DecimalFormat) NumberFormat.getInstance(locale);
            dcf.setMinimumFractionDigits(0);
            dcf.setMaximumFractionDigits(0);
            formattedValue = dcf.format(dcf.parse(_input));
         } else if(format.equals(NUMERIC_CURRENCY)) {
            float num = Float.parseFloat(_input);
            DecimalFormat dcf = (DecimalFormat)
            NumberFormat.getCurrencyInstance();
            formattedValue = dcf.format(num);
         }
      }
      catch (Exception e) {
         System.out.println(e.toString());
      }
      return formattedValue;
   }
   /* Attribute Accessor Methods */
   public String getFormat ()
   {
      return this.format;
   }
   public void setFormat (String _format)
   {
      this.format = _format;
   }
}

Finally, you have your JSP page. There's really nothing new here. The page declares a JavaBean to use as the model, sets values in the model, and displays those values in various formats. The formatting takes place through the FormatTag, specified in the helpers.tld file and declared in the JSP page using the taglib directive. Notice how you specify the format in an attribute of the custom tag. The format attribute should be set to a value corresponding to one of the static constants defined in the tag handler. Listing 5 shows the code for the JSP page.

Listing 5. formatHelper.jsp

 <%-- Declare tag that we'll use as our helper --%>
<%@ taglib uri="/helpers" prefix="helpers" %>
<html>
   <head>
      <title>Text Formatting Example</title>
   </head>
   <body>
      <font face="Arial"/>
      <%-- Declare bean that will act as our model --%>
      <jsp:useBean id="myBean" class="jspbook.ch08.beans.FormattingModel"/>
      <jsp:setProperty name="myBean" property="dateValue" value="12/01/01"/>
      <jsp:setProperty name="myBean" property="currencyValue" value="23500.253"/>
      <%-- Display Formatted Values (using helper) --%>
      <center>
         <h1>Various Date and Currency Formats</h1>
         <br/><br/>
         <table cellpadding="5">
            <tr>
               <th>Format</th>
               <th>Original Value</th>
               <th>Formatted Value</th>
            </tr>
            <tr>
               <td>Long Date</td>
               <td>
                  <jsp:getProperty name="myBean" property="dateValue"/>
               </td>
               <td>
                  <helpers:FormatTag format="date">
                     <jsp:getProperty name="myBean" property="dateValue"/>
                  </helpers:FormatTag>
                </td>
            </tr>
            <tr>
               <td>Decimal (NN.NN)</td>
               <td>${myBean.currencyValue}</td>
               <td>
                  <helpers:FormatTag format="decimal">
                     ${myBean.currencyValue}
                  </helpers:FormatTag>
               </td>
            </tr>
            <tr>
               <td>Integer (N,NNN)</td>
               <td>${myBean.currencyValue}</td>
               <td>
                  <helpers:FormatTag format="rounded">
                     ${myBean.currencyValue}
                  </helpers:FormatTag>
               </td>
            </tr>
            <tr>
               <td>Currency (N,NNN.NN)</td>
               <td>${myBean.currencyValue}</td>
               <td>
                  <helpers:FormatTag format="currency">
                     ${myBean.currencyValue}
                  </helpers:FormatTag>
               </td>
            </tr>
         </table>
      </center>
   </body>
</html>

Figure 4 shows the results of formatting a date value and a numeric value using each of the different formats provided by the tag handler.

Figure 4. Format text helper example. Click on thumbnail to view full-sized image.

Creating menus

It can be an advantage in some cases to dynamically generate menus or collections of hyperlinks. The controller would execute the appropriate action, which in turn would generate a list of link items. The view, using a helper, would generate a formatted menu containing the links stored in the model.

As an example, the view will be a JSP page that will display a menu screen listing accessory items for a specific product. This is a good example of why you may need to dynamically generate menu screens. Users presumably click a specific product in the company catalog and expect to see a list of accessories from which they can choose. This application pulls the necessary product information from the database and produces a set of product accessories to be displayed as hyperlinks within the view.

For this example, you'll skip the link-generation part and simply provide a static model with which to work. The model will be a JavaBean containing a hashtable of link items. The hashtable will be keyed by the text to display, storing the links as values. You'll retrieve the links as a comma-delimited list and insert it inside a custom tag. Listing 6 shows what the static model looks like.

Listing 6. MenuModel.java

 package jspbook.ch08.beans;
import java.io.Serializable;
import java.util.Hashtable;
import java.util.Enumeration;
public class MenuModel implements Serializable {
   Hashtable links = new Hashtable();
   String list = "";
   public MenuModel()
   {
      /* Initialize model with sample values */
      links.put("Fold-away Keyboard", "/Controller?action=display&item=101");
      links.put("Standard Leather Case", "/Controller?action=display&item=102");
      links.put("Deluxe 3-Pocket Case", "/Controller?action=display&item=103");
      links.put("Travel Cable", "/Controller?action=display&item=104");
      links.put("Stylus Pack", "/Controller?action=display&item=105");
      links.put("8MB Backup Module", "/Controller?action=display&item=106");
   }
   /* Accessor Methods */
   public void setList (String _list)
   {
      this.list = _list;
   }
   public String getList ()
   {
      StringBuffer csvList = new StringBuffer();
      /* Transform hashtable into comma-separated list */
      Enumeration enum = links.keys();
      while (enum.hasMoreElements()) {
         String linkName = (String) enum.nextElement();
         String linkURL = (String) links.get(linkName);
         csvList.append(linkName).append(",").append(linkURL).append("\n");
      }
      return csvList.toString();
   }
}

The helper you'll use is a custom tag that extends the BodyTagSupport class so that it can process the body content stored within its start and end tags. This custom tag needs to read in the list of link items and output a list of hyperlinks. It does this in the doAfterBody() method, looping through each line of the body content and parsing out the link name and the link URL. Note that if there's white space after the body content that's returned from the model, as there may well be if the page is formatted, then an extra line of spaces will be read in. You need to check for this. Listing 7 shows what the code looks like for your helper class.

Listing 7. MenuTag.java

 package jspbook.ch08;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.BodyContent;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class MenuTag extends BodyTagSupport {
   /* Tag Attributes */
   protected String links;
   /* Process Tag Body */
   public int doAfterBody() throws JspTagException {
      try {
         BodyContent body = getBodyContent();
         JspWriter out = body.getEnclosingWriter();
         /* Parse records and output as list of hyperlinks */
         BufferedReader contentReader = new BufferedReader(body.getReader());
         String record = "";
         while ((record = contentReader.readLine()) != null) {
            StringTokenizer st = new StringTokenizer(record, ",");
            while (st.hasMoreTokens()) {
               String linkName = st.nextToken();
               if(!linkName.trim().equals("")){
                  String linkURL = st.nextToken();
                  out.println("<a href='" + linkURL + "'>");
                  out.println(linkName + "</a>");
                  out.println("<br/><br/>");
               }
            }
         }
      }
      catch (IOException e) {
         throw new JspTagException(e.toString());
      }
      return SKIP_BODY;
   }
   /* Process End Tag */
   public int doEndTag() throws JspTagException {
      return EVAL_PAGE;
   }
   /* Attribute Accessor Methods */
   public String getLinks ()
   {
      return this.links;
   }
   public void setLinks (String _links)
   {
      this.links = _links;
   }
}

Using this tag in a JSP page is fairly simple, as intended. At the point you'd like to display the list of hyperlinks, you insert a custom tag to do the job for you. Inside the tag's body, you place a small snippet of EL code to retrieve the comma-separated list of link items. Because you're executing code inside the tag, you must declare the tag in your tag library descriptor file with the <bodycontent> tag containing the value jsp. Here's the full tag descriptor from the helpers.tld file and the code for the JSP page:

 <tag>
   <name>MenuTag</name>
   <tag-class>jspbook.ch08.MenuTag</tag-class>
   <body-content>jsp</body-content>
</tag>

Listing 8 shows the menuHelper.jsp page. The menu items are retrieved inside the MenuTag using the getList() method of the MenuModel JavaBean. The tag handler parses these items and outputs them as a list of hyperlinks (see Figure 5 for the results).

Listing 8. menuHelper.jsp

 <%-- Declare tag that we'll use as our helper --%>
<%@ taglib uri="/helpers" prefix="helpers" %>
<html>
   <head>
      <title>Product Accessories</title>
   </head>
   <body>
      <font face="Arial"/>
      <%-- Declare bean that will act as our model --%>
      <jsp:useBean id="myBean" class="jspbook.ch08.beans.MenuModel"/>
      <%-- Display Product Accessory Links (using helper) --%>
      <center>
         <b>Product Accessories for: Deluxe PDA</b>
         <br/><br/>
         <helpers:MenuTag>
            ${myBean.list}
         </helpers:MenuTag>
      </center>
   </body>
</html>
Figure 5. Menu helper example. Click on thumbnail to view full-sized image.

Creating custom list formats

A common element of most Web applications is a grouping of several related items displayed as a bulleted list. The standard HTML list element, using the <ul> tags, displays list items using a standard bullet. Using an appropriate helper to display the list enables you to customize the way the list is displayed. In this example, you'll build a helper that adapts a list of items to a formatted list with a selection of three different list styles. Here's the descriptor for the tag:

 <tag>
   <name>ListTag</name>
   <tag-class>jspbook.ch08.ListTag</tag-class>
   <body-content>jsp</body-content>
   <attribute>
      <name>format</name>
      <required>yes</required>
      <rtexprvalue>true</rtexprvalue>
   </attribute>
</tag>

The code for the tag defines the format attribute as in the FormatTag and processes its body content in much the same way as the MenuTag does. It's important to point out that a list can be formatted in many ways. In this example, you're simply double-spacing the list items and providing a choice of bullets. Listing 9 shows the code for the tag.

Listing 9. ListTag.java

 package jspbook.ch08;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.BodyContent;
import java.io.BufferedReader;
import java.io.IOException;
public class ListTag extends BodyTagSupport {
   /* Tag Attributes */
   protected String format;
   /* Static Constants */
   private final static String BULLET_ORB = "orb";
   private final static String BULLET_PLUS = "plus";
   private final static String BULLET_ARROW = "arrow";
   /* Process Tag Body */
   public int doAfterBody() throws JspTagException {
      try {
         BodyContent body = getBodyContent();
         JspWriter out = body.getEnclosingWriter();
         /* Parse records and output as formatted list */
         BufferedReader contentReader = new BufferedReader(body.getReader());
         String record = "";
         while ((record = contentReader.readLine()) != null) {
            if (record.trim().length() > 0) {
               out.println(formatListItem(record.trim()));
            }
         }
      }
      catch (IOException e) {
         throw new JspTagException(e.toString());
      }
      return SKIP_BODY;
    }
   /* Process End Tag */
   public int doEndTag() throws JspTagException {
      return EVAL_PAGE;
   }
   private String formatListItem (String _input)
   {
      StringBuffer listItem = new StringBuffer();
      /* Double-space the list */
      listItem.append("<br/><br/>");
      if(format.equals(BULLET_ORB)) {
         listItem.append("<img src='/jspBook/images/orb.gif'/>");
      } else if (format.equals(BULLET_PLUS)) {
         listItem.append("<img src='/jspBook/images/plus.gif'/>");
      } else if (format.equals(BULLET_ARROW)) {
         listItem.append("<img src='/jspBook/images/arrow.gif'/>");
      }
      listItem.append(" ").append(_input);
      return listItem.toString();
   }
   /* Attribute Accessor Methods */
   public String getFormat ()
   {
      return this.format;
   }
   public void setFormat (String _format)
   {
      this.format = _format;
   }
}

In this example, you could have built a JavaBean to hold the model as you did in previous examples, but you probably get the idea of how you use these helpers to adapt actual model data to presentation code. So, in your JSP page, you simply hard-code the list items into the tag bodies rather than pull the values out of a model.

Listing 10 shows the code for the JSP page. Figure 6 shows the formatted lists.

Listing 10. listHelper.jsp

 <%-- Declare tag that we'll use as our helper --%>
<%@ taglib uri="/helpers" prefix="helpers" %>
<html>
   <head>
      <title>List Examples</title>
   </head>
   <body>
      <font face="Arial"/>
      <center>
         <h1>List Examples</h1>
         <table width="650">
            <tr>
               <td valign="top" width="150">
                  <helpers:ListTag format="orb">
                     High Card
                     Pair
                     Two Pair
                     Three of a Kind
                     Straight
                     Flush
                     Full House
                     Four of a Kind
                     Straight Flush
                     Royal Flush
                  </helpers:ListTag>
               </td>
               <td valign="top" width="150">
                  <helpers:ListTag format="plus">
                     Milwaukee Bucks
                     Detroit Pistons
                     Toronto Raptors
                     Indiana Pacers
                     Charlotte Hornets
                     Cleveland Cavaliers
                     Atlanta Hawks
                     Chicago Bulls
                  </helpers:ListTag>
               </td>
               <td valign="top" width="300">
                  <helpers:ListTag format="arrow">
                     Chapter 1 - The History of Cheese
                     Chapter 2 - The Many Faces of Cheese
                     Chapter 3 - Love and Cheese
                     Chapter 4 - Not Just for Mice
                     Chapter 5 - So You're a Cheesehead...
                     Chapter 6 - The Perfect Cheese
                     Chapter 7 - Cheddar Is Better
                     Chapter 8 - The Big Cheese
                  </helpers:ListTag>
               </td>
            </tr>
         </table>
      </center>
   </body>
</html>
Figure 6. List helper example. Click on thumbnail to view full-sized image.

Summary

This concludes the discussion of the J2EE presentation patterns as applied to JSP pages and servlets. When used in combination, they can produce a powerful request-handling framework for enterprise Web applications.

Andrew Patzer is a Web architect for a consulting firm located in the Midwest. His first book, Professional Java Server Programming, is a bestseller and one of the first books to cover J2EE technologies. Patzer recently served as a lead systems architect for an industry-leading application service provider in the insurance industry. He was directly involved in designing and building a J2EE development framework upon which the company's key product was built. Patzer has delivered several presentations over the years to both local user groups and national conferences.

Learn more about this topic

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