2.7. Input/Output Mapping

Each flow has a well-defined input/output contract. Flows can be passed input attributes when they start, and can return output attributes when they end. In this respect, calling a flow is conceptually similar to calling a method with the following signature:

FlowOutcome flowId(Map<String, Object> inputAttributes);
		

... where a FlowOutcome has the following signature:

public interface FlowOutcome {
   public String getName();		        
   public Map<String, Object> getOutputAttributes();
}
		

input

Use the input element to declare a flow input attribute:

<input name="hotelId" />
			

Input values are saved in flow scope under the name of the attribute. For example, the input above would be saved under the name hotelId.

Declaring an input type

Use the type attribute to declare the input attribute's type:

<input name="hotelId" type="long" />
				

If an input value does not match the declared type, a type conversion will be attempted.

Assigning an input value

Use the value attribute to specify an expression to assign the input value to:

<input name="hotelId" value="flowScope.myParameterObject.hotelId" />
				

If the expression's value type can be determined, that metadata will be used for type coersion if no type attribute is specified.

Marking an input as required

Use the required attribute to enforce the input is not null or empty:

<input name="hotelId" type="long" value="flowScope.hotelId" required="true" />
				

output

Use the output element to declare a flow output attribute. Output attributes are declared within end-states that represent specific flow outcomes.

<end-state id="bookingConfirmed">
    <output name="bookingId" />  
</end-state>
			

Output values are obtained from flow scope under the name of the attribute. For example, the output above would be assigned the value of the bookingId variable.

Specifying the source of an output value

Use the value attribute to denote a specific output value expression:

<output name="confirmationNumber" value="booking.confirmationNumber" />  
				

Checkpoint: input/output mapping

Now review the sample booking flow with input/output mapping:

<flow xmlns="http://www.springframework.org/schema/webflow"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/webflow
                          http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">

    <input name="hotelId" />

    <on-start>
        <evaluate expression="bookingService.createBooking(hotelId, currentUser.name)" 
                  result="flowScope.booking" />
    </on-start>

    <view-state id="enterBookingDetails">
        <transition on="submit" to="reviewBooking" />
    </view-state>
	
    <view-state id="reviewBooking">
        <transition on="confirm" to="bookingConfirmed" />
        <transition on="revise" to="enterBookingDetails" />
        <transition on="cancel" to="bookingCancelled" />
    </view-state>
	
    <end-state id="bookingConfirmed" >
        <output name="bookingId" value="booking.id"/>
    </end-state>

    <end-state id="bookingCancelled" />
		
</flow>	
			

The flow now accepts a hotelId input attribute and returns a bookingId output attribute when a new booking is confirmed.