JSF 2.2: Flow Calls
Join the DZone community and get the full member experience.
Join For FreeIn this tutorial, we will consider Faces Flow calls. For a basic level of information about Faces Flow, please check out this article and, for information about the usage of flows, you can check out JSF 2.2: Use Faces Flow tutorial.
Here, we will expand the sample application from the previous tutorial in a way that will allow the customer and order flows to call each other. This way, when an order flow is called from a customer flow, the recorded customer’s name, surname and address information is passed as a parameter to the order flow. When a customer flow is called from an order flow, the order's product, price and billing address information is passed as a parameter to the customer flow.
1. Project directory structure
2. Project dependencies

<dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0-b72</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.faces</artifactId> <version>2.2.0</version> <scope>provided</scope> </dependency>3. Customer.java
public class Customer implements Serializable { @Produces @FlowDefinition public Flow defineFlow(@FlowBuilderParameter FlowBuilder flowBuilder) { String flowId = "customer"; flowBuilder.id("", flowId); flowBuilder.viewNode(flowId, "/" + flowId + "/" + flowId + ".xhtml").markAsStartNode(); flowBuilder.returnNode("returnFromCustomerFlow") .fromOutcome("#{customerBean.returnValue}"); flowBuilder.inboundParameter("productOrder", "#{flowScope.productOrder}"); flowBuilder.inboundParameter("priceOrder", "#{flowScope.priceOrder}"); flowBuilder.inboundParameter("adressLine1Order", "#{flowScope.adressLine1Order}"); flowBuilder.inboundParameter("adressLine2Order", "#{flowScope.adressLine2Order}"); flowBuilder.inboundParameter("cityOrder", "#{flowScope.cityOrder}"); flowBuilder.inboundParameter("stateOrder", "#{flowScope.stateOrder}"); flowBuilder.inboundParameter("postalCodeOrder", "#{flowScope.postalCodeOrder}"); flowBuilder.inboundParameter("countryOrder", "#{flowScope.countryOrder}"); flowBuilder.flowCallNode("callOrder").flowReference("", "order") .outboundParameter("firstNameCustomer", "#{customerBean.firstName}") .outboundParameter("lastNameCustomer", "#{customerBean.lastName}") .outboundParameter("adressLine1Customer", "#{customerBean.adressLine1}") .outboundParameter("adressLine2Customer", "#{customerBean.adressLine2}") .outboundParameter("cityCustomer", "#{customerBean.city}") .outboundParameter("stateCustomer", "#{customerBean.state}") .outboundParameter("postalCodeCustomer", "#{customerBean.postalCode}") .outboundParameter("countryCustomer", "#{customerBean.country}"); return flowBuilder.getFlow(); } }The InboundParameter method adjusts the names and values of incoming parameters from the order flows. The FlowCallNode method defines how a customer flow calls an order flow. The “callOrder” argument that was passed to the method defines the action of calling the flow. The chained flowReference method defines the actual name of the flow to call. When the order flow is called, the outboundParameter method is called in order to define the parameters to be passed. For an explanation of the remaining code, you can check out the previous tutorial. 4. order-flow.xml
<flow-definition id="order"> <flow-return id="returnFromOrderFlow"> <from-outcome>#{orderBean.returnValue}</from-outcome> </flow-return> <inbound-parameter> <name>firstNameCustomer</name> <value>#{flowScope.firstNameCustomer}</value> </inbound-parameter> <inbound-parameter> <name>lastNameCustomer</name> <value>#{flowScope.lastNameCustomer}</value> </inbound-parameter> <inbound-parameter> <name>adressLine1Customer</name> <value>#{flowScope.adressLine1Customer}</value> </inbound-parameter> <inbound-parameter> <name>adressLine2Customer</name> <value>#{flowScope.adressLine2Customer}</value> </inbound-parameter> <inbound-parameter> <name>cityCustomer</name> <value>#{flowScope.cityCustomer}</value> </inbound-parameter> <inbound-parameter> <name>stateCustomer</name> <value>#{flowScope.stateCustomer}</value> </inbound-parameter> <inbound-parameter> <name>postalCodeCustomer</name> <value>#{flowScope.postalCodeCustomer}</value> </inbound-parameter> <inbound-parameter> <name>countryCustomer</name> <value>#{flowScope.countryCustomer}</value> </inbound-parameter> <flow-call id="callCustomer"> <flow-reference> <flow-id>customer</flow-id> </flow-reference> <outbound-parameter> <name>productOrder</name> <value>#{orderBean.product}</value> </outbound-parameter> <outbound-parameter> <name>priceOrder</name> <value>#{orderBean.price}</value> </outbound-parameter> <outbound-parameter> <name>adressLine1Order</name> <value>#{orderBean.adressLine1}</value> </outbound-parameter> <outbound-parameter> <name>adressLine2Order</name> <value>#{orderBean.adressLine2}</value> </outbound-parameter> <outbound-parameter> <name>cityOrder</name> <value>#{orderBean.city}</value> </outbound-parameter> <outbound-parameter> <name>stateOrder</name> <value>#{orderBean.state}</value> </outbound-parameter> <outbound-parameter> <name>postalCodeOrder</name> <value>#{orderBean.postalCode}</value> </outbound-parameter> <outbound-parameter> <name>countryOrder</name> <value>#{orderBean.country}</value> </outbound-parameter> </flow-call> </flow-definition>In this code, the XML configuration is similar to the programmatic configuration. Incoming parameters for the order flow are defined with the inbound-parameter element. Flow-call elements define how an order flow will call a customer flow. The "callCustomer" argument that is passed to the ID attribute of the element defines the action of calling the flow. Flow-reference elements within the element defines the actual name of the flow for the call. When a customer flow is called, parameters to be passed are defined by the outboundParameter element. For an explanation of the remaining parts of the XML configuration, you can check out the previous tutorial. 5. CustomerBean.java – OrderBean.java
@Named @FlowScoped("customer") public class CustomerBean implements Serializable { private String firstName; private String lastName; private String adressLine1; private String adressLine2; private String city; private String state; private String postalCode; private String country; public CustomerBean() { System.out.println("CustomerBean has been created..."); } public String getName() { return this.getClass().getSimpleName(); } public String getReturnValue() { return "/index"; } /* getter and setter methods */ }6. Demo application

Flow (web browser)
Opinions expressed by DZone contributors are their own.
Trending
-
Essential Architecture Framework: In the World of Overengineering, Being Essential Is the Answer
-
A Deep Dive Into the Differences Between Kafka and Pulsar
-
Revolutionizing System Testing With AI and ML
-
Software Development: Best Practices and Methods
Comments