JSF Navigation Model

Jsf framework is provided with navigation rules which describes the view to be displayed and how the control moves in an application.

Navigation can be as simple as hard coding like- confirm or confirm.xhtml.

Let's have a test.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
	<h:head>
    	<title>Simple JavaServer Faces Application</title>
	</h:head>
<h:body>
 <h:form>
   <h2>JSF App</h2>
   <p><h:messages /></p>
   <p><h:commandButton value="Allow" action="confirm" /></p>
 </h:form>
</h:body>
</html>

When user clicks on confirm then will redirected to confirm.xhtml page.

Suppose we want to apply some business logic after clicking on button and then navigate to another page like:

<h:commandButton value="Confirm" 
             action="#{sampleBean.allowUser}"/>

And allowUser method is defined in sampleBean as:

public String allowUser() {
	// add any business logic and then return
	return confirm;
}

JSF has the h:commandButton, h:commandLink, h:button, and h:link components which all can be used for navigation. Markup for these components must include an action attribute (in the case of h:commandButton and h:commandLink) or an outcome attribute (in the case of h:button and h:link).

Value of that attribute can either be a literal string, hard-coded into the page, or an EL expression that points to a method that returns a String (or actually any Java Object with a toString( ) method).

Navigation Rules in faces-config.xml:

We can specify navigation rules in faces-config.xml as:

<navigation-rule>
<from-view-id>page.xhtml</from-view-id>
	<navigation-case>
	<from-action>#{sampleBean.actionMethod}</from-action>
	<from-outcome>success</from-outcome>
	<to-view-id>/success.xhtml</to-view-id>
	</navigation-case>

	<navigation-case>
	<from-action>#{sampleBean.actionMethod}</from-action>
	<from-outcome>fail</from-outcome>
	<to-view-id>/failure.xhtml</to-view-id>
	</navigation-case>
</navigation-rule>

With this above specified rule- when we hit the button from page.xhtml page then sampleBean.actionMethod will get executed and then depending upon execution either success and failure will be returned which will rforward the user to success.xhtml or failure.xhtml page

Differences between h:button/h:link and h:commandButton/h:commandLink.

First, h:button/h:link causes the browser to issue an HTTP GET request, while h:commandButton/h:commandLink does a form POST. This means that any components in the page that have values entered by the user, such as text fields, checkboxes, etc., will not automatically be submitted to the server when using h:button/h:link.

The second main difference between the two kinds of components is that h:button/ h:link has an outcome attribute to describe where to go next while h:commandButton/ h:commandLink uses an action attribute.

Forward vs Redirect:

JSF by default performs a server page forward while navigating to another page and the URL of the application do not changes.

To enable the page redirection, append faces-redirect=true at the end of the view name.

<h:form>
   <h2>Forward</h2>
   <h:commandButton action="forward" value="ForwardPage" />
   <h2>Redirect</h2>
   <h:commandButton action="redirect?faces-redirect=true" 
	         value="RedirectPage" />
</h:form>

In Navigation rule we can define redirect as:

<navigation-case>
  <from-action>#{login.loginAction}</from-action>
  <from-outcome>success</from-outcome>
  <to-view-id>/success.xhtml</to-view-id>
  <redirect/>
</navigation-case>

If <redirect/> is not defined then by default it is forward.