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(); }
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
.
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.
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.
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.
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.