The techniques of the preceding sections should be sufficient for most practical navigation needs. In this section, we describe the remaining rules for the navigation elements that can appear in the faces-config.xml file. Figure 3-7 shows a syntax diagram of the valid elements. Figure 3-7. Syntax Diagram for Navigation Elements NOTE | As you saw in Chapter 2, it is also possible to place the navigation information into configuration files other than the standard faces-config.xml file. |
As you can see from the syntax diagram, each navigation-rule and navigation-case element can have arbitrary description, display-name, and icon elements. These elements are intended for use in builder tools, and we do not discuss them further. Redirection If you add a redirect element after to-view-id, then the JSP container terminates the current request and sends an HTTP redirect to the client. The redirect response tells the client which URL to use for the next page. Redirecting the page is slower than forwarding because another round trip to the browser is involved. However, the redirection gives the browser a chance to update its address field. Figure 3-6 shows how the address field changes when you add a redirection element as follows:
<navigation-case> <from-outcome>success</from-outcome> <to-view-id>/success.jsp</to-view-id> <redirect/> </navigation-case> Without redirection, the original URL (localhost:8080/javaquiz/index.faces) is unchanged when the user moves from the /index.jsp page to the / success.jsp face. With redirection, the browser di splays the new URL (localhost:8080/javaquiz/success.faces). Figure 3-8. Redirection Updates the URL in the Browser TIP | Use the redirect element for pages that the user might want to bookmark. |
Wildcards You can use wildcards in the from-view-id element of a navigation rule, for example:
<navigation-rule> <from-view-id>/secure/*</from-view-id> <navigation-case> . . . </navigation-case> </navigation-rule> This rule applies to all pages that start with the prefix /secure/. Only a single * is allowed, and it must be at the end of the ID string. If there are multiple matching wildcard rules, the longest match is taken. NOTE | Instead of leaving out a from-view-id element, you can also use one of the following to specify a rule that applies to all pages:
<from-view-id>/*</from-view-id>
or
<from-view-id>*</from-view-id>
|
Using from-action The structure of the navigation-case element is more complex than we previously discussed. In addition to the from-outcome element, there is also a from-action element. That flexibility can be useful if you have two separate actions with the same action string, or two action method references that return the same action string. For example, suppose that in our quiz application, the startOverAction returns the string "again" instead of "startOver". The same string can be returned by the answerAction. To differentiate between the two navigation cases, you can use a from-action element. The contents of the element must be identical to the method reference string of the action attribute.
<navigation-case> <from-action>#{quiz.answerAction}</from-action> <from-outcome>again</from-outcome> <to-view-id>/again.jsp</to-view-id> </navigation-case> <navigation-case> <from-action>#{quiz.startOverAction}</from-action> <from-outcome>again</from-outcome> <to-view-id>/index.jsp</to-view-id> </navigation-case> NOTE | The navigation handler does not invoke the method inside the #{...} delimiters. The method has been invoked before the navigation handler kicks in. The navigation handler merely uses the from-action string as a key to find a matching navigation case. |
The Navigation Algorithm We finish this chapter with a description of the precise algorithm that the navigation handler uses to resolve ambiguous situations. Feel free to skip this section for now and come back when you have to decipher rules produced by other programmers or automated tools. The algorithm has three inputs: The outcome, that is, the value of an action attribute or the string resulting from the invocation of a method reference. The view ID of the current view The action, that is, the literal value of the action attribute in the component that triggered the navigation. The first of two phases is to find the matching navigation-rule, following these steps. - If the outcome is null, return immediately and redisplay the current page.
- Merge all navigation rules with the same from-view-id value.
- Try to find a navigation rule whose from-view-id value matches the view ID exactly. If such a rule exists, take it.
- Consider all navigation rules whose from-view-id values end with a wildcard suffix, such as secure. For each such rule, check whether the prefix (after removing the *) is identical to the corresponding prefix of the view ID. If there are matching rules, take the one with the longest matching prefix.
- If there is a rule without a from-view-id, take it.
- If there is no match at all, redisplay the current page.
The second of two phases is to consider all navigation-case elements in the matching navigation rule (which may consist of several merged navigation-rule elements with matching from-view-id.values). Follow these steps to find the matching case. - If a case has both matching from-outcome and from-action, take it.
- Otherwise, if a case has matching from-outcome and no from-action, take it.
- Otherwise, if a case has matching from-action and no from-outcome, take it.
- Otherwise, if there is a case with neither from-outcome or from-action, take it.
- If there is no match at all, redisplay the current page.
Naturally, we recommend that you do not create tricky navigation rules in your own programs. As long as you stay away from wildcards and from-action elements, you won't need to know about the gory details of the navigation algorithm. |