Sun Java Solaris Communities My SDN Account Join SDN
 
Enterprise BluePrints

Java BluePrints > Enterprise > Patternsn

 


Guidelines, Patterns, and code for end-to-end Java applications.

Java BluePrints > Enterprise > Patterns

View Helper

Brief Description

Business classes change frequently, and application views change even more frequently. Coupling between business and presentation logic complicates maintenance and reuse.

A View Helper is a class that does data retrieval for the view. It adapts a data resource to a simple API usable by application views. The View Helper pattern decouples business and application classes from one another and allows them to vary at their own rates. Decoupling also promotes reuse, because each business or presentation component has fewer dependencies. So the view can focus on formatting and presentation logic, and let the View Helper handle the processing and retrieval of data.

Detailed Description

Detailed Example

The Java BluePrints Program recommendation for presentation on browser clients is to use JavaServer Pages (JSP) pages as view components. Two common strategies for implementing View Helpers is the JavaBean helper strategy and the custom tag helper strategy. JSP pages offer technologies that are useful for implementing View Helper: the useBean tag and custom tags. The Java Pet Store website uses a View Helper called CatalogHelper as a view helper for several views. It also uses the JavaServer Pages Standard Tag Library (JSTL) technology to adapt the CatalogHelper methods to the needs of JSP pages.

  • Using the CatalogHelper View Helper from a JSP page.

    The class CatalogHelper handles and hides the complexity of accessing the Java Pet Store sample application catalog, and presents a simplified interface to its clients. The CatalogHelper is an example of the JavaBean Helper strategy.

    • The sequence diagram in Figure 1 shows how the View Helper accesses a data resource on behalf of the view. In the diagram, the view component is a JSP page class, generated from the JSP page source code by the JSP page compiler. In this example, the JSP page accesses the CatalogHelper in two ways: directly, using the useBean tag, and indirectly, by way of JSTL tags.
      Figure 1. Structure diagram of View Helper pattern
    • Sample application view component category.jsp defines an instance of CatalogHelper in session scope with the useBean tag, as follows:
                      
      <jsp:useBean
        id="catalog"
        class="com.sun.j2ee.blueprints.catalog.client.CatalogHelper"
        scope="session"
      />
          
                    

    • The tag above defines an HttpSession attribute catalog of type CatalogHelper. Later tags in the page create a variable called pageResults, which is the result of a call to CatalogHelper method getProducts:
                      
      
      <c:choose>
       <c:when test="${param.count != null}">
        <c:set value="${param.start}" target="${catalog}" property="start"/>
        <c:set value="${param.count}" target="${catalog}" property="count"/>
       </c:when>
       <c:otherwise>
        <c:set value="0" target="${catalog}" property="start"/>
        <c:set value="2" target="${catalog}" property="count"/>
       </c:otherwise>
      </c:choose>
      <c:set value="en_US" target="${catalog}" property="locale"/>
      <c:set value="${param.category_id}" target="${catalog}" property="categoryId"/>
      <c:set value="${catalog.products}" var="pageResults" />
      
          
                    

    • The block of tags above initializes method call arguments for the invocation of CatalogHelper method getProducts (by accessing attribute catalog.products in the last line). It then invokes the method on the View Helper object, and places the Page of results in a variable called pageResults. The CatalogHelper manages and hides the complex process of selecting a data source, fetching product data from the data source, and encapsulating those data as a Page object. The code that accesses data from the CatalogDAO appears in the code sample below.
                      
      Page getProductsFromDAO(String categoryId, int start, int count, Locale locale) 
              throws CatalogClientException {
              try {
                  if (dao == null) 
                      dao = CatalogDAOFactory.getDAO();          
                  return dao.getProducts(categoryId, start, count, 
                                         locale);
              } 
              catch (CatalogDAOSysException se) {
                  System.out.println("Exception reading data from dao " + se);
                  throw new CatalogClientException(se.getMessage());
              }
          }    
          
                    

    • The DAO code above gets the products directly using a JDBC query, as shown below (this code is actually from CloudscapeCatalogDAO ):
                      
          
      public Page getProducts(String categoryID, int start,
                              int count, Locale l) 
        throws CatalogDAOSysException {
         
          Connection c = null;
          PreparedStatement ps = null;
          ResultSet rs = null;
          Page ret = null;
      
          try {
              c = getDataSource().getConnection();
      
              // Select
              ps = c.prepareStatement("select a.productid, name, descn "
                                      + "from (product a join "
                                      + "product_details b on "
                                      + "a.productid=b.productid) "
                                      + "where locale = ? "
                                      + "and a.catid = ? "
                                      + "order by name",
                                      ResultSet.TYPE_SCROLL_INSENSITIVE,
                                      ResultSet.CONCUR_READ_ONLY);
              ps.setString(1, l.toString());
              ps.setString(2, categoryID);
              rs = ps.executeQuery();
              // ... and so on ...
          
          
                    

    • Finally, again in products.jsp, the following block of tags formats the contents of the Page object (which was created by the code above, and kept in session scope). The JSTL tags (in XML namespace c:) iterate the Page collection and extract and format the catalog product data in the resulting page:
                      
      <c:forEach var="item" items="${pageResults.list}" >
      <tr>
       <td class="petstore_listing">
          <c:url value="/product.screen" var="productURL">
           <c:param name="product_id" value="${item.id}"/>
          </c:url>
          <a href='<c:out value="${productURL}"/>'>
          <c:out value="${item.name}"/>
         </a>
         <br>
         <c:out value="${item.description}"/>
        </td>
       </tr>
      </c:forEach>    
      
          
          
                    

    The key point to understand in this example is that all of the code that manages data source selection and data access is in the View Helper, not in scriptlets in the JSP page.

    Also, note that the View Helper pattern may be combined with other patterns. For example, the View Helper may use a Business Delegate or Service Locator to help manage the data access. The Java Pet Store sample application illustrates the use of the View Helper pattern combined with other patterns as part of its overall design.