Download PDF Home History |  | API Search Feedback FAQ

> ## JavaServer Faces Version of Coffee Break Server

> JavaServer Faces is designed to provide a clean separation of the presentation layer and the model layer so that you can readily add JavaServer Faces functionality to existing applications. In fact almost all of the original Coffee Break Server back-end code remains the same in the JavaServer Faces technology version of the server.

> This section provides some details on how the JavaServer Faces version of the Coffee Break server is different from the non-GUI framework version. Like the non-GUI framework version of the Coffee Break server implementation, the JavaServer Faces Coffee Break server is organized along the Model-View-Controller design pattern. Instead of the `Dispatcher` servlet examining the request URL, creating and initializing model JavaBeans components, and dispatching requests to view JSP pages, now the `FacesServlet` (included with the JavaServer Faces API), performs these tasks. As a result, the `Dispatcher` servlet has been removed from the JavaServer Faces version of the Coffee Break server. Some of the code from the `Dispatcher` has been moved to beans. This will be explained later in this section.

> As with the non-GUI framework version of the Coffee Break server, the JavaServer Faces Coffee Break server includes JavaBeans components that contain the business logic for the application: they call the Web services and perform computations on the data returned from the services. The JSP pages format the data stored in the JavaBeans components. The mapping between JavaBeans components and pages is summarized in Table 35-2.

> Table 35-2 Model and View Components
> Function | JSP Page | JavaBeans Component
> --- | --- | ---
> Update order data | `orderForm` | `CoffeeBreakBean, ShoppingCart`
> Update delivery and billing data | `checkoutForm` | `CheckoutFormBean`
> Display order confirmation | `checkoutAck` | `OrderConfirmations`

> ### JSP Pages

> #### orderForm

> As in the non-GUI framework version of the Coffee Break server, the `orderForm` displays the current contents of the shopping cart. The first time the page is requested, the quantities of all the coffees are 0. Each time the customer changes the coffee amounts and clicks the Update button, the request is posted back to `orderForm`.

> The `CoffeeBreakBean` bean component updates the values in the shopping cart, which are then redisplayed by `orderForm`. When the order is complete, the customer proceeds to the `checkoutForm` page by clicking the Checkout button.

> The table of coffees displayed on the `orderForm` is rendered using one of the JavaServer Faces component tags, `dataTable`. Here is part of the `dataTable` tag from `orderForm`:

>     <h:dataTable id="table"
>       columnClasses="list-column-center,list-column-right,
>         list-column-center, list-column-right"
>       headerClass="list-header" rowClasses="list-row"
>       footerClass="list-column-right"
>       styleClass="list-background-grid"
>       value="#{CoffeeBreakBean.cart.items}" var="sci">
>       <f:facet name="header">
>         <h:outputText  value="#{CBMessages.OrderForm}"/>
>       </f:facet>
>       <h:column>
>         <f:facet name="header">
>           <h:outputText  value="Coffee"/>
>         </f:facet>
>         <h:outputText id="coffeeName"
>           value="#{sci.item.coffeeName}"/>
>       </h:column>
>       ...
>     </h:dataTable>

> When this tag is processed, a `UIData` component and a `Table` renderer are created on the server side. The `UIData` component supports a data binding to a collection of data objects. The `Table` renderer takes care of generating the HTML markup. The `UIData` component iterates through the list of coffees, and the `Table` renderer renders each row in the table.

> This example is a classic use case for a `UIData` component because the number of coffees might not be known to the application developer or the page author at the time the application is developed. Also, the `UIData` component can dynamically adjust the number of rows in the table to accommodate the underlying data.

> For more information on `UIData`, please see The UIData Component.

> #### checkoutForm

> `checkoutForm` is used to collect delivery and billing information for the customer. When the Submit button is clicked, an `ActionEvent` is generated. This event is first handled by the `submit` method of the `checkoutFormBean`. This method acts as a listener for the event because the tag corresponding to the submit button references the `submit` method with its `action` attribute:

>     <h:commandButton value="#{CBMessages.Submit}"
>       action="#{checkoutFormBean.submit}"/>

> The `submit` method submits the suborders to each supplier and stores the result in the request-scoped `OrderConfirmations` bean.

> The `checkoutForm` page has standard validators on several components and a custom validator on the email component. Here is the tag corresponding to the `firstName` component, which holds the customer's first name:

>     <h:inputText id="firstName"
>       value="#{checkoutFormBean.firstName}"
>       size="15" maxlength="20" required="true"/>

> With the `required` attribute set to `true`, the JavaServer Faces implementation will check whether the user entered something in the First Name field.

> The `email` component has a custom validator registered on it. Here is the tag corresponding to the `email` component:

>     <h:inputText id="email" value="#{checkoutFormBean.email}"
>       size="25" maxlength="125"
>       validator="#{checkoutFormBean.validateEmail}"/>

> The `validator` attribute refers to the `validateEmail` method on the `CheckoutFormBean` class. This method ensures that the value the user enters in the email field contains an @ character.

> If the validation does not succeed, the `checkoutForm` is re-rendered, with error notifications in each invalid field. If the validation succeeds, `checkoutFormBean` submits suborders to each supplier and stores the result in the request-scoped `OrderConfirmations` JavaBeans component and control is passed to the `checkoutAck` page.

> #### checkoutAck

> `checkoutAck` simply displays the contents of the `OrderConfirmations` JavaBeans component, which is a list of the suborders constituting an order and the ship dates of each suborder. This page also uses a `UIData` component. Again, the number of coffees the customer ordered is not known before runtime. The `UIData` component dynamically adds rows to accommodate the order.

> ### JavaBeans Components

> The JavaBeans components in the JavaServer Faces version of the Coffee Break server are almost the same as those in the original version. This section highlights what has changed and describes the new components.

> #### CheckoutFormBean

> The `validate` method of the original version of the`CheckoutFormBean` checks the completeness of information entered into `checkoutForm`. Because JavaServer Faces technology automatically validates certain kinds of data when the appropriate validator is registered on a component, the `validate` method of `checkoutFormBean` is not necessary in the JavaServer Faces version of that bean.

> Several of the tags on the `checkoutForm` page have their `required` attributes set to `true.` This will cause the implementation to check whether the user enters values in these fields. The tag corresponding to the `email` component registers a custom validator on the `email` component, as explained in checkoutForm. The code that performs the validation is the `validateEmail` method:

>     public void validateEmail(FacesContext context,
>       UIComponent toValidate, Object value) {
>       String message = "";
>       String email = (String) value;
>       if (email.indexOf('@') == -1) {
>         ((UIInput)toValidate).setValid(false);
>         message = CoffeeBreakBean.loadErrorMessage(context,
>           CoffeeBreakBean.CB_RESOURCE_BUNDLE_NAME,
>             "EMailError");
>         context.addMessage(toValidate.getClientId(context),
>           new FacesMessage(message));
>       }
>     }

> As in the non-GUI framework version of the Coffee Break server, if the information is incomplete or invalid, the page is rerendered to display the error messages. If the information is complete, order requests are constructed from the shopping cart and the information supplied to `checkoutForm` and are sent to each supplier.

> #### CoffeeBreakBean

> `CoffeeBreakBean` is exclusive to the JavaServer Faces technology version of the Coffee Break server. It acts as the backing bean to the JSP pages. See Backing Bean Management for more information on backing beans. `CoffeeBreakBean` creates the `ShoppingCart` object, which defines the model data for the components on the `orderForm` page that hold the data about each coffee. `CoffeeBreakBean` also loads the `RetailPriceList` object. In addition, it provides the methods that are invoked when the buttons on the `orderForm` and `checkoutAck` are clicked. For example, the `checkout` method is invoked when the Checkout button is clicked because the tag corresponding to the Checkout button refers to the `checkout` method via its `action` attribute:

>     <h:commandButton id="checkoutLink"
>       value="#{CBMessages.Checkout}"
>       action="#{CoffeeBreakBean.checkout}" />

> The `checkout` method returns a `String`, which the JavaServer Faces page navigation system matches against a set of navigation rules to determine what page to access next. The navigation rules are defined in a separate XML file, described in the next section.

> ### Resource Configuration

> A JavaServer Faces application usually includes an XML file that configures resources for the application. These resources include JavaBeans components, navigation rules, and others.

> Two of the resources configured for the JavaServer Faces version of the Coffee Break server are the `CheckoutForm` bean and navigation rules for the `orderForm` page:

>     <managed-bean>
>       <managed-bean-name>checkoutFormBean</managed-bean-name>
>       <managed-bean-class>
>         com.sun.cb.CheckoutFormBean
>       </managed-bean-class>
>       <managed-bean-scope>request</managed-bean-scope>
>         <managed-property>
>           <property-name>firstName</property-name>
>           <value>Coffee</value>
>         </managed-property>
>         <managed-property>
>           <property-name>lastName</property-name>
>           <value>Lover</value>
>         </managed-property>
>         <managed-property>
>           <property-name>email</property-name>
>           <value>jane@home</value>
>         </managed-property>
>         ...
>       </managed-bean>
>     <navigation-rule>
>       <from-view-id>/orderForm.jsp</from-view-id>
>       <navigation-case>
>         <from-outcome>checkout</from-outcome>
>         <to-view-id>/checkoutForm.jsp</to-view-id>
>       </navigation-case>
>     </navigation-rule>

> As shown in the `managed-bean` element, the `checkoutForm` bean properties are initialized with the values for the user, Coffee Lover. In this way, the hyperlink tag from `orderForm` is not required to submit these values in the request parameters.

> As shown in the navigation-rule element, when the `String`, `checkout`, is returned from a method referred to by a component's `action` attribute, the `checkoutForm` page displays.

Download PDF Home History |  | API Search Feedback FAQ

All of the material in The J2EE(TM) 1.4 Tutorial is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.