JSF 2.2: Use Faces Flow

We will consider the use of Faces Flow in this tutorial. For a basic level of information about Faces Flow, you can take a look at this article: Faces Flow

I used the following tools and technologies in the sample application that I have developed for this tutorial:

  • JSF version 2.2
  • GlassFish version 4.0
  • JDK version 1.7
  • Maven version 3.0.5

Sample application has the customer and the order flows. Customer flow records the customer’s name, surname and address; order flow records the product, price and invoice address of the order.


1. Project directory structure

Screen Shot 2013-06-30 at 8.45.34 PM


2. Project dependencies



3. Customer.java

public class Customer implements Serializable {
    public Flow defineFlow(@FlowBuilderParameter FlowBuilder flowBuilder) {
        String flowId = "customer";
        flowBuilder.id("", flowId);
        flowBuilder.viewNode(flowId, "/" + flowId + "/" + flowId + ".xhtml").markAsStartNode();
        return flowBuilder.getFlow();

Customer class is a java class that configures a flow with the same name. The only method this class has returns the javax.faces.flow.Flow class. What need to be done primarily in the method is to define flow identity. Then, start node and return node is defined for flow.


4. order-flow.xml

<flow-definition id="order">
        <flow-return id="returnFromOrderFlow">

The preceding flow configuration file is a faces configuration file that includes a flow-definition element. If xml configuration file is used in order to configure a flow, this file must be entitled as flowName-flow.xml. Please pay attention this file which configures a flow namely order is located within the same named flow directory.

First of all in the configuration file, flow identity must be defined by using id attribute of flow-definition element. Under this element, there must be flow-return element also which defines the return point for flow.


5. CustomerBean.java – OrderBean.java

public class CustomerBean implements Serializable {

    public CustomerBean() {
        System.out.println("CustomerBean has been created...");
    public String getName() {
        return this.getClass().getSimpleName();

    public String getReturnValue() {
        return "/index";
public class OrderBean implements Serializable {

    public OrderBean() {
        System.out.println("OrderBean has been created...");
    public String getName() {
        return this.getClass().getSimpleName();

    public String getReturnValue() {
        return "/index";

FlowScoped is a CDI scope. A class has @FlowScoped annotation is taken into account within the flow scope that is specified in run time. Bean is activated when you enter the flow and deactivated when you exit the flow. The method namely getReturnValue that both beans have returns the value of the return node.


6. index.xhtml

 <h1>Welcome to kodcu.com Faces Flow tutorial</h1>
        <h:form prependId="false">
                <p>Click Customer to register your customer information and enter the customer flow.</p>
                <h:commandButton value="Customer" action="customer"/>
                <p>Click Order to register your order information and enter the order flow.</p>
                <h:commandButton value="Order" action="order"/>

Please note that the flows namely customer and order are called by “customer” and “order” arguments in which commandButton components are passed to action attribute. These two arguments specify the call action of relevant flows.


7. order.xhtml

<h:form prependId="false">
            <h:panelGrid columns="3" cellpadding="2" cellspacing="2">
                <h:outputLabel for="product" value="Product: "/>
                <h:inputText  id="product" value="#{flowScope.product}" required="true" maxlength="20"/>
                <h:message for="product"/>
                <h:outputLabel for="price" value="Price: "/>
                <h:inputText id="price" value="#{flowScope.price}" required="true">
                    <f:convertNumber pattern="#,##0.00"/>
                <h:message for="price"/>
                    <h:commandButton value="next" action="orderA" />
                    <h:commandButton immediate="true" action="returnFromOrderFlow" value="Exit Flow"/>

New EL object #{flowScope} obtains the current flow data and maps the flow data for facesContext.getApplication().getFlowHandler().getCurrentFlowScope(). The object is also introduced as a local storage for flows.


8. Demo application

Screen Shot 2013-06-30 at 10.06.18 PM

In the next article, we will consider the flow calls and how flows pass parameters to each other.

Demo application: Faces Flow

No Comments

Post a Comment