Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

JSF Navigation Tutorial - Declarative Navigation

Check also:
The three golden rules of use
JSF Navigation Tutorial - Implicit Navigation
JSF VS Series: Implicit Navigation VS Declarative (explicit) Navigation

Declarative navigationrefers to defining the navigation cases in faces-config.xml via a bunch of dedicated tags. Before implicit navigation, this was the only way to navigate after an action. These days  the implicit navigation is available, so declarative navigation is considered obsolete (officially speaking they are not obsolete or deprecated!). But, since this is a navigation tutorial we cannot simply ignore declarative navigation, therefore let's have a quick intro and some examples.
In order to navigate, JSF needs the well-known coordinates: view ID, logical outcome and/or Action Expression Signature. Only that this time they are described in the faces-config.xmldescriptor using XML-based rules, as follow:

This tag wraps the navigation cases of a specific view ID.

<from-view-id/>
This is a child of <navigation-rule/>and it defines the view ID from which we navigate.

<navigation-case/>
This is a child of <navigation-rule/>and it wraps a single navigation case characterized by view ID, logical outcome and/or action expression signature. There can be multiple navigation cases.

<from-outcome/>
This tag is a child of <navigation-case/>and represents the logical outcome.

<from-action/>
This tag is a child of <navigation-case/>and represents an action expression signature (optional).

<to-view-id/>
This tag is a child of <navigation-case/>and represents the view ID that resolve the logical outcome and/or action expression signature.

<redirect/>
This tag is a child of <navigation-case/>and instructs JSF that the navigation should be accomplish via PRG. By default, JSF will navigate via POST request based in forward mechanism.

For example, check the below navigation items:

<h:link value="Success" outcome="success"/>
<h:button value="Success" outcome="success"/>

<h:commandButton value="Success" action="success"/>
<h:commandLink value="Success" action="success"/>

The declarative version of this is as follows—thanks to implicit navigation, this code
is not needed:

<navigation-rule>
 <from-view-id>*</from-view-id>
 <navigation-case>
  <from-outcome>success</from-outcome>
  <to-view-id>/success.xhtml</to-view-id>
 </navigation-case>
</navigation-rule>

Let's see some more examples. The managed bean used in the next examples is listed first and the application is named DeclarativeNavigation:

@Named
@RequestScoped
public class TheBean {

 private static final Logger LOG = Logger.getLogger(TheBean.class.getName());   

 public String theActionWithDoneOutcome() {
  LOG.info("TheBean#theActionWithDoneOutcome() called ...");
  return "done";
 }
   
 public String theActionWithOutcomeForSuccess() {
  LOG.info("TheBean#theActionWithOutcomeForSuccess() called ...");
  return "doneFromTheActionWithOutcome";
 }
   
 public String theActionWithOutcomeForFailure() {
  LOG.info("TheBean#theActionWithOutcomeForFailure() called ...");
  return "doneFromTheActionWithOutcome";
 }   
   
 public String theActionWithRedirectForSuccess() {
  LOG.info("TheBean#theActionWithRedirectForSuccess() called ...");
  return "doneFromTheActionWithRedirect";
 }
   
 public String theActionWithRedirectForFailure() {
  LOG.info("TheBean#theActionWithRedirectForFailure() called ...");
  return "doneFromTheActionWithRedirect";
 }
}

FIRE A JSF GET REQUEST AND NAVIGATE TO THE VIEW ID COMPUTED FROM THE SPECIFIED OUTCOME
JSF will interpret the outcome value of <h:link/>/<h:button/> as the targeted page name (done becomes success.xhtmlvia declarative navigation)

<h:link value="Click me!" outcome="done"/>
<h:button value="Click me! " outcome="done"/>

Declaratively, we have:

<navigation-rule>
 <from-view-id>index.xhtml</from-view-id>
 <navigation-case>
  <from-outcome>done</from-outcome>
  <to-view-id>/success.xhtml</to-view-id>
 </navigation-case>
</navigation-rule>

FIRE A JSF GET REQUEST. PROVIDE THE NAVIGATION OUTCOME VIA A SERVER-SIDE METHOD CALLED DURING COMPUTING THE VIEW ID (AT RENDERING TIME)
JSF will interpret the outcome value of <h:link/>/<h:button/> as the targeted page name (done returned by theActionWithDoneOutcome() becomes success.xhtmlvia declarative navigation)

<h:link value="Click me!" outcome="#‌{theBean.theActionWithDoneOutcome()}"/>
<h:button value="Click me!" outcome="#‌{theBean.theActionWithDoneOutcome()}"/>

Declaratively, we have:

<navigation-rule>
 <from-view-id>index.xhtml</from-view-id>
 <navigation-case>
  <from-outcome>done</from-outcome>
  <to-view-id>/success.xhtml</to-view-id>
 </navigation-case>
</navigation-rule>

FIRE (SUBMIT) A POST REQUEST VIA FORWARD MECHANISM AND NAVIGATE TO THE VIEW ID COMPUTED FROM THE SPECIFIED OUTCOME
JSF will interpret the action value of <h:commandLink/Button/> as the targeted page name (done becomes success.xhtmlvia declarative navigation)

<h:form>
 <h:commandLink value="Click Me!" action="done"/>
 <h:commandButton value="Click Me!" action="done"/>
</h:form>

Declaratively, we have:

<navigation-rule>
 <from-view-id>index.xhtml</from-view-id>
 <navigation-case>
  <from-outcome>done</from-outcome>
  <to-view-id>/success.xhtml</to-view-id>
 </navigation-case>
</navigation-rule>

FIRE (SUBMIT) A POST REQUEST VIA REDIRECT MECHANISM AND NAVIGATE TO THE VIEW ID COMPUTED FROM THE SPECIFIED OUTCOME
The presence of <redirect/> in navigation case will instruct JSF to rely on POST-redirect-GET (PRG) navigation pattern

<h:form>
 <h:commandLink value="Click Me!" action="doneredirect"/>
 <h:commandButton value="Click Me!" action="doneredirect"/>
</h:form>

Declaratively, we have:

<navigation-rule>
 <from-view-id>index.xhtml</from-view-id>
 <navigation-case>
  <from-outcome>doneredirect</from-outcome>
  <to-view-id>/success.xhtml</to-view-id>
  <redirect/>
 </navigation-case>
</navigation-rule> 

FIRE (SUBMIT) A POST REQUEST VIA FORWARD MECHANISM. INVOKE AN ACTION METHOD AND NAVIGATE TO THE VIEW ID COMPUTED BASED ON THE OUTCOME RETURNED BY THIS METHOD
The action can point to an action method that returns a String. This string is considered the outcome and it will be interpreted as the targeted page name (doneFromtheActionWithOutcome becomes success/failure.xhtml via declarative navigation)

// theActionWithOutcomeForSuccess() → doneFromTheActionWithOutcome → success.xhtml
<h:form>
 <h:commandLink value="Click Me!" action="#‌{theBean.theActionWithOutcomeForSuccess()}"/>
 <h:commandButton value="Click Me!" action="#‌{theBean.theActionWithOutcomeForSuccess()}"/>
</h:form>

// theActionWithOutcomeForFailure() → doneFromTheActionWithOutcome → failure.xhtml
<h:form>
 <h:commandLink value="Click Me!" action="#‌{theBean.theActionWithOutcomeForFailure()}"/>
 <h:commandButton value="Click Me!" action="#‌{theBean.theActionWithOutcomeForFailure()}"/>
</h:form>

Declaratively, we have:

<navigation-rule>
 <from-view-id>index.xhtml</from-view-id>
 <navigation-case>
  <from-outcome>doneFromTheActionWithOutcome</from-outcome>
  <from-action>#{theBean.theActionWithOutcomeForSuccess()}</from-action>
  <to-view-id>/success.xhtml</to-view-id>
 </navigation-case>
 <navigation-case>
  <from-outcome>doneFromTheActionWithOutcome</from-outcome>
  <from-action>#{theBean.theActionWithOutcomeForFailure()}</from-action>
  <to-view-id>/failure.xhtml</to-view-id>
 </navigation-case>
</navigation-rule>

FIRE (SUBMIT) A POST REQUEST VIA REDIRECT MECHANISM. INVOKE AN ACTION METHOD AND NAVIGATE TO THE VIEW ID COMPUTED BASED ON THE OUTCOME RETURNED BY THIS METHOD
The presence of <redirect/> in navigation case will instruct JSF to rely on POST-redirect-GET (PRG) navigation pattern

// theActionWithRedirectForSuccess() → doneFromTheActionWithRedirect → success.xhtml
<h:form>
 <h:commandLink value="Click Me!" action="#‌{theBean.theActionWithRedirectForSuccess()}"/>
 <h:commandButton value="Click Me!" action="#‌{theBean.theActionWithRedirectForSuccess()}"/>
</h:form>

// theActionWithRedirectForFailure() → doneFromTheActionWithRedirect → failure.xhtml
<h:form>
 <h:commandLink value="Click Me!" action="#‌{theBean.theActionWithRedirectForFailure()}"/>
 <h:commandButton value="Click Me!" action="#‌{theBean.theActionWithRedirectForFailure()}"/>
</h:form>

Declaratively, we have:

<navigation-rule>
 <from-view-id>index.xhtml</from-view-id>
 <navigation-case>
  <from-outcome>doneFromTheActionWithRedirect</from-outcome>
  <from-action>#{theBean.theActionWithRedirectForSuccess()}</from-action>
  <to-view-id>/success.xhtml</to-view-id>
  <redirect/>
 </navigation-case>
 <navigation-case>
  <from-outcome>doneFromTheActionWithRedirect</from-outcome>
  <from-action>#{theBean.theActionWithRedirectForFailure()}</from-action>
  <to-view-id>/failure.xhtml</to-view-id>
  <redirect/>
 </navigation-case>
</navigation-rule>

The complete application is available here.


This post first appeared on OmniFaces & JSF Fans, please read the originial post: here

Share the post

JSF Navigation Tutorial - Declarative Navigation

×

Subscribe to Omnifaces & Jsf Fans

Get updates delivered right to your inbox!

Thank you for your subscription

×