Previous Section  < Day Day Up >  Next Section

1.2 How Does JSF Compare to Traditional Technologies?

JSF brings a component-based model to web application development that is similar to the model that's been used in standalone GUI applications for years. Let's look at some of the advantages this gives you compared to more traditional web application technologies.

1.2.1 Less Code in the User Interface Templates

Java web applications user interfaces have typically been implemented as a set of JSP pages (or pages for similar template-engine technologies, such as Velocity or FreeMarker), where static content (e.g., text and HTML elements for layout) is mixed with elements that generate dynamic content when the page is processed. A problem with this approach is that the pages often end up with logic for maintaining the user interface state—for instance, code for marking checkboxes and list items as selected and for displaying current values in input fields.

When you use JSF with JSP as the presentation layer technology, special elements (JSP custom actions) represent the JSF components. Here's a snippet of a page with a form showing a user's food preferences as a set of HTML checkboxes:

    ...

    <h:form>

      <table>

      ...

        <tr>

          <td>Favorite Foods:</td>

          <td>

            <h:selectManyCheckbox value="#{cust.foodSelections}">

              <f:selectItem itemValue="z" itemLabel="Pizza" />

              <f:selectItem itemValue="p" itemLabel="Pasta" />

              <f:selectItem itemValue="c" itemLabel="Chinese" />

            </h:selectManyCheckbox>

          </td>

        </tr>

        ...

      </table>

    </h:form>

    ...

The details are not important at this stage, but note that there are no loops or conditional tests in the page. This logic is instead encapsulated in the JSF components represented by the <h:selectManyCheckbox> and <f:selectItem> elements. When the form is submitted, the JSF framework saves the list of current selections in an application object on the server (referenced by the #{cust.foodSelection} expression specified by the value attribute in this example). When the response is rendered, JSF uses the list to check off the corresponding boxes. Separating logic from the layout in this manner makes the page author's life easier.

With JSP as the presentation layer, the page author must still learn how to use the special JSF elements, and many standard page development tools don't know how to deal with them. As I mentioned earlier, JSF supports presentation layer technologies other than JSP. No alternative is fully described by the specification, but one can be implemented on top of the JSF API by third parties or in-house staff. Such a presentation layer may allow you to use just plain markup elements (e.g., HTML) in the templates instead. Anyone familiar with the markup language can then develop the user interface look and feel using standard tools, while Java programmers create JSF components that take care of the dynamic parts of the page:

    ...

    <form action="validate_jstl.jsp" method="post">

      <table>

      ...

        <tr>

          <td>Favorite Foods:</td>

          <td>

            <input id="pizza" type="checkbox" name="food" value="z">Pizza<br>

            <input id="pasta" type="checkbox" name="food" value="p">Pasta<br>

            <input id="chinese" type="checkbox" name="food" value="c">Chinese<br>

          </td>

        </tr>

        ...

      </table>

    </form>

    ...

The only thing that's a bit out of the ordinary here is the id attribute for the elements representing dynamic content. An identifier like this is typically needed by the custom presentation layer to tie JSF components to the elements in the template, so the components know which element to modify. We'll look at a custom presentation layer implementation that uses this approach at the end of this book.

Even for such a simple example (a page with a few checkboxes), both of these sample pages are a lot simpler to develop and maintain than a traditional JSP page with the same functionality. Here's a typical plain JSP page version of this example:

    ...

    <form action="validate_jstl.jsp" method="post">

      <table>

      ...

        <c:forEach items="${paramValues.food}" var="current">

          <c:choose>

            <c:when test="${current == 'z'}"> 

              <c:set var="pizzaSelected" value="true" />

            </c:when>

            <c:when test="${current == 'p'}"> 

              <c:set var="pastaSelected" value="true" />

            </c:when>

            <c:when test="${current == 'c'}"> 

              <c:set var="chineseSelected" value="true" />

            </c:when>

          </c:choose>

        </c:forEach>

        <tr>

          <td>Favorite Foods:</td>

          <td>

            <input type="checkbox" name="food" value="z"

              ${pizzaSelected ? 'checked' : ''}>Pizza<br>

            <input type="checkbox" name="food" value="p"

              ${pastaSelected ? 'checked' : ''}>Pasta<br>

            <input type="checkbox" name="food" value="c"

              ${chineseSelected ? 'checked' : ''}>Chinese

          </td>

        </tr>

        ...

      </table>

    </form>

    ...

If you're not familiar with JSP and the JSP Standard Tag Library (JSTL), don't worry about the details. The main thing to note is that this page contains a lot of code (in the form of XML-like JSP action elements and Expression Language expressions, but it's still code) in addition to the HTML elements. It first loops through all values received through a request parameter named food and sets flags when it finds values it recognizes. It then uses these flags to decide whether to add a checked attribute for the corresponding checkbox elements it generates. That's quite a mouthful (pun intended) for something as simple as handling food choices. Imagine the amount of code needed in a page that displays all kinds of dynamic state, such as the one in Figure 1-1.

Figure 1-1. A complex web application user interface
figs/Jsf_0101.gif

This is the main screen for the sample application we'll develop in this book. It contains numerous buttons that are enabled or disabled depending on who's logged in and the business object status, plus scrollable and sortable tables and input fields that keep their previous values between requests. The application must also distinguish between different types of requests, triggered by clicking different buttons and links. For an application like that, JSF really shines.

1.2.2 More Modular User Interface Code

The web application architecture most experienced developers recommend is loosely based on the Model-View-Controller (MVC) design pattern. MVC was first described by Xerox in a number of papers published in the late 1980s, in conjunction with the Smalltalk language. This model has since been used for GUI applications developed in all popular programming languages. The basic idea is to separate the application data and business logic, the presentation of the data, and the interaction with the data into distinct entities labeled the Model, the View, and the Controller, respectively.

The Model represents pure business data and the rules for how to use this data; it knows nothing about how the data is displayed or the user interface controls used to modify the data. The View, on the other hand, knows all about the user interface details. It also knows about the public Model interface for reading its data, so that it can render it correctly, and it knows about the Controller interface, so it can ask the Controller to modify the Model. Using the MVC design pattern results in a flexible application in which multiple presentations (Views) can be provided and easily modified, and changes in the business rules or physical representation of the data (the Model) can be made without touching any of the user interface code.

While Java web application frameworks like Struts support the MVC model on a high level, it's not supported in the same strict, fine-granular way as in a GUI framework. For example, in Struts, the View is represented by a set of JSP pages, the Controller by a Struts servlet that delegates the real work to Action classes, and the Model by application classes that typically interact with a database or some other permanent storage. The interfaces between the different pieces, however, are not defined as a set of specific methods with declared parameters. Instead, control is passed between the pieces using generic methods, and the data the next piece needs is made available through coarse-grained collections—such as collections of all HTTP request parameters, headers, attributes, and so on. Another major difference between a GUI framework and a typical web application framework is that the latter only recognizes one type of event: the HTTP request. The code that handles this coarse-grained event has to dig through the request data to tell if the user has entered new data in any fields, asked for a different type of presentation by selecting an option in a menu, ordered a transaction to be completed, or something else. A GUI framework, on the other hand, is based on fine-granular events, such as "value changed," "menu item selected," and "button clicked," with separate event handlers dealing with each event.

The JSF MVC design is similar to Swing and other GUI frameworks, as shown in Figure 1-2.

Figure 1-2. JThe JSF MVC design
figs/Jsf_0102.gif

The Model is represented by properties of application objects, e.g., a username property on an application object holding user information. JSF UI components declare what events they can fire, such as "value changed" and "button clicked" events, and external event listeners (representing the Controller) attached to the components handle these events. An event listener may set properties of the JSF components—for instance, adjust the set of rows shown in a table—or invoke backend code that processes the submitted data (say, verify that a credit card is valid or update a database). A separate renderer class (representing the View) renders each JSF UI component, making it possible to render instances of the same component type in different ways (e.g., either as a button or a link, or using different markup languages) just by attaching different renderers.

Besides the UI components, JSF also defines artifacts like validators and converters, each with a well-defined purpose. The end result is a very modular user interface code model that is easy to maintain, familiar to GUI application developers, and lends itself well to tools support.

    Previous Section  < Day Day Up >  Next Section