Download FAQ History |  | API Search Feedback

> ## Navigating Between Pages

> As explained in section Navigation Model, this release of JavaServer Faces technology includes a new navigation model that eliminates the need to define navigation rules programmatically with an `ApplicationHandler`.

> Now you define page navigation rules in a centralized XML file called the application configuration resource file. See Application Configuration for more information on this file.

> Any additional processing associated with navigation that you might have included in an `ApplicationHandler` you now include in an `Action` class. An `Action` object is referenced by the `UICommand` component that triggers navigation. The `Action` object returns a logical outcome based on the results of its processing. This outcome describes what happened during the processing. The Action that was invoked and the outcome that is returned are two criteria a navigation rule uses for choosing which page to navigate to.

> This rest of this section explains:

> - What navigation is
> - How an application navigates between pages
> - How to define navigation rules in the application configuration file
> - How to include any processing associated with page navigation in an `Action` class
> - How to reference an `Action` class from a component tag

> ### What is Navigation?

> Navigation is a set of rules for choosing a page to be displayed. The selection of the next page is determined by:

> - The page that is currently displayed
> - The `Action` that was invoked by a `UICommand` component's `actionRef` property
> - An outcome string that was returned by the `Action` or passed from the component.

> A single navigation rule defines how to navigate from one particular page to any number of other pages in an application. The JavaServer Faces implementation chooses the proper navigation rule according to what page is currently displayed.

> Once the proper navigation rule is selected, the choice of which page to access next from the current page depends on the `Action` that was invoked and the outcome that was returned.

> The `UICommand` component either specifies an outcome from its `action` property or refers to an `Action` object with its `actionRef` property. The `Action` object performs some processing and returns a particular outcome string.

> The outcome can be anything the developer chooses, but Table 21-17 on page 886 lists some outcomes commonly used in Web applications.

> Table 21-17 Common outcome strings
> Outcome | What it means
> --- | ---
> "success" | Everything worked. Go on to the next page
> "error" | Something is wrong. Go on to an error page
> "logon" | The user needs to log on first. Go on to the logon page.
> "no results" | The search did not find anything. Go to the search page again.

> Usually, the `Action` class performs some processing on the form data of the current page. For example, the `Action` class might check if the username and password entered in the form match the username and password on file. If they match, the `Action` returns the outcome "success". Otherwise, it returns the outcome "failure". As this example demonstrates, both the `Action` and the outcome are necessary to determine the proper page to access.

> Here is a navigation rule that could be used with the example `Action` class processing described in the previous paragraph:

>     <navigation-rule>
>       <from-tree-id>logon.jsp</from-tree-id>
>       <navigation-case>
>         <from-action-ref>LogonForm.logon</from-action-ref>
>         <from-outcome>success</from-outcome>
>         <to-tree-id>/storefront.jsp</to-tree-id>
>       </navigation-case>
>       <navigation-case>
>         <from-action-ref>LogonForm.logon</from-action-ref>
>         <from-outcome>failure</from-outcome>
>         <to-tree-id>/logon.jsp</to-tree-id>
>         </navigation-case>
>     </navigation-rule>

> This navigation rule defines the possible ways to navigate from `logon.jsp`. Each `navigation-case` element defines one possible navigation path from `logon.jsp`. The first `navigation-case` says that if `LogonForm.logon` returns an outcome of "success", `storefront.jsp` will be accessed. The second `navigation-case` says that `logon.jsp` will be re-rendered if `LogonForm.logon` returns "failure".

> For a complete description of how to define navigation rules, see Configuring Navigation Rules in faces-config.xml.

> The next section describes what happens behind the scenes when navigation occurs.

> ### How Navigation Works

> As section The Lifecycle of a JavaServer Faces Page explains, a JavaServer Faces page is represented by a component tree, which is comprised of all of the components on a page. To load another page, the JavaServer Faces implementation accesses a component tree identifier and stores the tree in the `FacesContext`. The new navigation model determines how this tree is selected.

> Any `UICommand` components in the tree are automatically registered with the default `ActionListenerImpl`. When one of the components is activated--such as by a button click--an `ActionEvent` is emitted. If the Invoke Application phase is reached, the default `ActionListenerImpl` handles this event.

> The `ActionListenerImpl` retrieves an outcome--such as "success" or "failure"--from the component generating the event. The `UICommand` component either literally specifies an outcome with its `action` property or refers to a JavaBeans component property of type `Action` with its `actionRef` property. The `invoke` method of the `Action` object performs some processing and returns a particular outcome string.

> After receiving the outcome string, the `ActionListenerImpl` passes it to the default `NavigationHandler`. Based on the outcome, the currently displayed page, and the `Action` object that was invoked, the `NavigationHandler` selects the appropriate component tree by consulting the application configuration file (`faces-config.xml`).

> The next section explains how to define navigation rules for your application in the `faces-config.xml` file.

> ### Configuring Navigation Rules in faces-config.xml

> An application's navigation configuration consists of a set of navigation rules. Each rule is defined by the `navigation-rule` element in the `faces-config.xml` file. See Setting Up The Application Configuration File for information on how to set up the `faces-config.xml` file for use in your application.

> Here are two example navigation rules:

>     <navigation-rule>
>       <from-tree-id>/more.jsp</from-tree-id>
>       <navigation-case>
>         <from-outcome>success</from-outcome>
>         <to-tree-id>/buy.jsp</to-tree-id>
>       </navigation-case>
>       <navigation-case>
>         <from-outcome>out of stock</from-outcome>
>         <from-action-ref>
>           CarOptionServer.carBuyAction
>         </from-action-ref>
>         <to-tree-id>/outofstock.jsp</to-tree-id>
>       </navigation-case>
>     </navigation-rule>
>     <navigation-rule>
>       <navigation-case>
>         <from-outcome>error</from-outcome>
>         <to-tree-id>/error.jsp</to-tree-id>
>       </navigation-case>
>     </navigation-case>

> The first navigation rule in this example says that the application will navigate from `more.jsp` to:

> - `buy.jsp` if the item ordered is in stock.
> - `outofstock.jsp` if the item is out of stock.

> The second navigation rule says that the application will navigate from any page to `error.jsp` if the application encountered an error.

> Each `navigation-rule` element corresponds to one component tree identifier, defined by the optional `from-tree-id` element. This means that each rule defines all the possible ways to navigate from one particular page in the application. If there is no `from-tree-id` element, the navigation rules defined in the `navigation-rule` element apply to all the pages in the application. The `from-tree-id` element also allows wildcard matching patterns. For example, this `from-tree-id` element says the navigation rule applies to all the pages in the `cars` directory:

>     <from-tree-id>/cars/*</from-tree-id>

> As shown in the example navigation rule, a `navigation-rule` element can contain zero or more `navigation-case` elements. The `navigation-case` element defines a set of matching criteria. When these criteria are satisfied, the application will navigate to the page defined by the `to-tree-id` element contained in the same `navigation-case` element.

> The navigation criteria are defined by optional `from-outcome` and `from-action-ref` elements.

> The `from-outcome` element defines a logical outcome, such as "success". The `from-action-ref` element refers to a bean property that returns an `Action` object. The `Action` object's `invoke` method performs some logic to determine the outcome and returns the outcome.

> The `navigation-case` elements are checked against the outcome and the `Action` parameters in this order:

> - Cases specifying both a `from-outcome` value and a `from-action-ref` value. Both of these elements can be used if the `Action`'s `invoke` method returns different outcomes depending on the result of the processing it performs.
> - Cases specifying only a `from-outcome` value. The `from-outcome` element must match either the outcome defined by the `action` attribute of the `UICommand` component or the outcome returned by the `Action` object referred to by the `UICommand` component.
> - Cases specifying only a `from-action-ref` value. This value must match the `Action` instance returned by the `UICommand` component.

> Once any of these cases are matched, the component tree defined by the `to-tree-id` element will be selected for rendering.

> The section Referencing An Action From a Component explains how to write the tag corresponding to the `UICommand` component to return an outcome.

> ### Referencing An Action From a Component

> The `command_button` and `command_hyperlink` tags have two attributes used to specify an outcome, which is matched against the `from-outcome` elements in the application configuration file in order to select the next page to be rendered. These attributes are:

> - `action`: This attribute defines a literal outcome value
> - `actionRef`: This attribute identifies a bean property that returns an `Action`, whose `invoke` method is executed when this button is clicked. This `invoke` method returns an outcome string.

> This `command_button` tag could be used with the example navigation rule from the previous section:

>     <h:command_button id="buy2" key="buy" bundle="carDemoBundle"
>         commandName="buy" actionRef="CarServer.carBuyAction">

> The `actionRef` attribute refers to `CarOptionServer.carBuyAction`, a bean property that returns an `Action` object, whose `invoke` method returns the logical outcome.

> If the outcome matches an outcome defined by a `from-outcome` element in application configuration file the component tree specified in that navigation case is selected for rendering if one of these is true:

> - No `from-action-ref` is also defined for that navigation case
> - There is a `from-action-ref` also defined for that navigation case, and the `Action` it identifies matches the `Action` identified by the command component's `actionRef` attribute.

> Suppose that the buy2 `command_button` tag used the `action` attribute instead of the `actionRef` attribute:

>     <h:command_button id="buy2" key="buy" bundle="carDemoBundle"
>         commandName="buy" action="out-of-stock">

> If this outcome matches an outcome defined by a `from-outcome` element in the application configuration file, the component tree corresponding to this navigation case is selected for rendering, regardless of whether or not the same navigation case also contains a `from-action-ref` element.

> The next section explains how to write the bean and the `Action` class.

> ### Using an Action Object With a Navigation Rule

> It's common for applications to have a choice of pages to navigate to from a given page. You usually need to provide some application-specific processing that determines which page to access in a certain situation. The processing code goes into the `invoke` method of an `Action` object. Here is the `Action` bean property and the `Action` implementation used with the examples in the previous two sections:

>     import javax.faces.application.Action;
>     ...
>     public class CurrentOptionServer extends Object{
>     ...
>       public Action getCarBuyAction() {
>         if (carBuyAction == null) {
>           carBuyAction = new CarBuyAction();
>         return carBuyAction;
>       }
>       class CarBuyAction extends Action {
>         public String invoke() {
>           if (carId == 1 && currentPackageName.equals("Custom") &&
>             currentPackage.getSunRoofSelected()) {
>               currentPackage.setSunRoofSelected(false);
>             return "out of stock";
>           } else {
>             return "success"
>           }
>       }
>     }

> The `CarBuyAction.invoke` method checks if the first car is chosen, the Custom package is chosen and the sunroof option is selected. If this is true, the `sunroof` checkbox component value is set to false, and the method returns the outcome, "out of stock". Otherwise, the outcome, "success" is returned.

> As shown in the example in section Configuring Navigation Rules in faces-config.xml, when the NavigationHandler receives the "out-of-stock" outcome, it selects the `/outofstock.jsp` component tree.

> As shown in the example code in this section, it's a good idea to include your `Action` class inside the same bean class that defines the property returning an instance of the `Action`. This is because the `Action` class will often need to access the bean's data to determine what outcome to return. Section Combining Component Data and Action Objects discusses this concept in more detail.

Download FAQ History |  | API Search Feedback

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