The Java EE 5 Tutorial

Writing a Method to Handle Navigation

A backing bean method that handles navigation processing, called an action method, must be a public method that takes no parameters and returns an Object, which is the logical outcome that the navigation system uses to determine what page to display next. This method is referenced using the component tag’s action attribute.

The following action method in CashierBean is invoked when a user clicks the Submit button on the bookcashier.jsp page. If the user has ordered more than $100 (or 100 euros) worth of books, this method sets the rendered properties of the fanClub and specialOffer components to true. This causes them to be displayed on the page the next time the page is rendered.

After setting the components’ rendered properties to true, this method returns the logical outcome null. This causes the JavaServer Faces implementation to re-render the bookcashier.jsp page without creating a new view of the page. If this method were to return purchase (which is the logical outcome to use to advance to bookcashier.jsp, as defined by the application configuration resource file), the bookcashier.jsp page would re-render without retaining the customer’s input. In this case, you want to re-render the page without clearing the data.

If the user does not purchase more than $100 (or 100 euros) worth of books or the thankYou component has already been rendered, the method returns receipt.

The default NavigationHandler provided by the JavaServer Faces implementation matches the logical outcome, as well as the starting page (bookcashier.jsp) against the navigation rules in the application configuration resource file to determine which page to access next. In this case, the JavaServer Faces implementation loads the bookreceipt.jsp page after this method returns.

public String submit() {
    ...
    if(cart().getTotal() > 100.00 &&
         !specialOffer.isRendered())
    {
        specialOfferText.setRendered(true);
        specialOffer.setRendered(true);
        return null;
    } else if (specialOffer.isRendered() &&
         !thankYou.isRendered()){
        thankYou.setRendered(true);
        return null;
    } else {
        clear();
        return ("receipt");
    }
}

Typically, an action method will return a String outcome, as shown in the previous example. Alternatively, you can define an Enum class that encapsulates all possible outcome strings and then make an action method return an enum constant, which represents a particular String outcome defined by the Enum class. In this case, the value returned by a call to the Enum class’s toString method must match that specified by the from-outcome element in the appropriate navigation rule configuration defined in the application configuration file.

The Duke’s Bank example uses an Enum class to encapsulate all logical outcomes:

public enum Navigation  {
    main, accountHist, accountList, atm, atmAck, transferFunds,
     transferAck, error
}

When an action method returns an outcome, it uses the dot notation to reference the outcome from the Enum class:

public Object submit(){
    ...
    return Navigation.accountHist;
}

Referencing a Method That Performs Navigation explains how a component tag references this method. Binding a Component Instance to a Bean Property discusses how the page author can bind these components to bean properties. Writing Properties Bound to Component Instances discusses how to write the bean properties to which the components are bound. Configuring Navigation Rules provides more information on configuring navigation rules.