My JSF Books/Videos My JSF Tutorials OmniFaces/JSF PPTs
JSF 2.3 Tutorial
JSF Caching Tutorial
JSF Navigation Tutorial
JSF Scopes Tutorial
JSF Page Author Beginner's Guide
OmniFaces 2.3 Tutorial Examples
OmniFaces 2.2 Tutorial Examples
JSF Events Tutorial
OmniFaces Callbacks Usages
JSF State Tutorial
JSF and Design Patterns
JSF 2.3 New Features (2.3-m04)
Introduction to OmniFaces
25+ Reasons to use OmniFaces in JSF
OmniFaces Validators
OmniFaces Converters
JSF Design Patterns
Mastering OmniFaces
Reusable and less-verbose JSF code

My JSF Resources ...

Java EE Guardian
Member of JCG Program
Member MVB DZone
Blog curated on ZEEF
OmniFaces is an utility library for JSF, including PrimeFaces, RichFaces, ICEfaces ...

[OmniFaces Utilities] - Find the right JSF OmniFaces 2 utilities methods/functions

Search on blog

Petition by Java EE Guardians

Twitter

luni, 7 martie 2016

JSF Navigation Tutorial - Declarative Navigation

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

Declarative navigation refers 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.xml descriptor using XML-based rules, as follow:

<navigation-rule/>
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.xhtml via 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.xhtml via 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.xhtml via 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.

Niciun comentariu :

Trimiteți un comentariu

JSF BOOKS COLLECTION

Postări populare

Follow by Email

Visitors Starting 4 September 2015

Locations of Site Visitors