States are first-class elements of a web flow. As a flow executes, it transitions from one state to another state, performing some action, making some decision, or displaying some output at each step of the way.
As mentioned before, there are five kinds of state in Spring Web Flow. These five states are expressed in a flow definition file using the five XML elements in the following table:
XML Element |
Description |
<action-state> |
Performs one or more actions. The outcome of an action may determine the transition to be taken to the next state in the flow. |
<decision-state> |
Evaluates one or more expressions to decide the next step in the flow. |
<decision-state> |
Denotes the final state of a flow. Upon entry to the end state, the flow is terminated. |
<subflow-state> |
Starts another flow as a subflow. |
<view-state> |
A state that involves the user in the flow by presenting them with some output and possibly prompting them for input |
View States
View states are used to display information to a user or to prompt the user for input. The actual view implementation is usually a JSP page, but can be any view that is supported by Spring MVC. View states are defined in the flow definition XML file with the <view-state> element.
<view-state> Children
<view-state> Child |
Description |
<attribute> |
Along with a nested <value> element, <attribute> declares a meta attribute to describe or annotate the state. |
<binder> |
Used to configure custom form binding. |
<exception-handler> |
References a <bean> (through the bean attribute) that implements FlowExecutionExceptionHandler that should handle exceptions thrown in this state. |
<on-entry> |
Specifies actions (evaluations, setting of variables, and/or fragment render requests) to be performed upon entry to this state. |
<on-exit> |
Specifies actions (evaluations, setting of variables, and/or fragment render requests) to be performed as exiting this state. |
<on-render> |
Specifies actions (evaluations, setting of variables, and/or fragment render requests) to be performed as rendering this state's view. |
<secured> |
Used with Spring Security to restrict access to this state given the current user's security attributes. |
<transition> |
Defines a path from this state to another state based on an event or exception. May optionally execute one or more actions in the course of the transition. |
<var> |
Declares a view instance variable. |
<view-state> Diagram
Defining a simple view state
The simplest possible view state involves only the <view-state> element with its id attribute set:
<view-state id=“welcome” />
With nothing else specified, this view state assumes a logical view name of “welcome” (the same as the state's ID). And, although no transitions are declared here, there may be some global transitions in play allowing the flow to transition away from this state.
Explicitly specifying the view
The convention of assuming a view name that is the same as the view state's ID is convenient. But if you'd rather explicitly specify the view name, then set it via the <view-state>'s view attribute:
<view-state id=“welcome” view=“startPage” />
Transitioning away from a view state
More typically, a view state will have one or more transitions that lead the flow away from the state. Here's the “welcome” state with two transitions defined:
<view-state id=“welcome”>
<transition to=“lookupCustomer” on=“phoneEntered” />
<transition to=“endState” on=“cancel” />
</view-state>
The to attribute of the <transition> element indicates the state to which the flow should transition after this state. The on attribute specifies the name of an event that should trigger the transition. In this case, the flow will transition to the “lookupCustomer” state if a “phoneEntered” event occurs in this state; or to the “endState” state if a “cancel” event is encountered.
Leaving off the on attribute causes a transition to take place regardless of what event occurs.
<view-state id=“thankYou”>
<transition to=“endState” />
</view-state>
In this case, the next stop after the “thankYou” view state will always be the state whose ID is “endState”.
Firing events from the view
Events can be fired from the view in one of three ways.
1. With a simple link:
<a href=“${flowExecutionUrl}&_eventId=finished”>Finish</a>
Spring Web Flow provides the ${flowExecutionUrl} variable with a URL path to the flow. The _eventId parameter specifies the event to be triggered.
2. Passing the event ID in a hidden field:
<form:form>
<input type=“hidden” name=“_flowExecutionKey” value=“${flowExecutionKey}” />
<input type=“hidden” name=“_eventId” value=“finished” />
<input type=“submit” value=“Finished” />
</form:form>
3. Specified in the name of a submit button:
<form:form>
<input type=“hidden” name=“_flowExecutionKey” value=“${flowExecutionKey}” />
<input type=“submit” name=“_eventId_finished” value=“Finished” />
</form:form>
Take notice of how the name of the submit button is structured. Rather than just name it with the event ID, the event ID is prefixed with “_eventId_”.
Action States
Whereas view states offer the users of the application to be involved in the flow, action states are where the application itself goes to work. Action states are defined by the <actionstate> element.
<action-state> Children
<action-state> Child |
Description |
<attribute> |
Along with a nested <value> element, <attribute> declares a meta attribute to describe or annotate the state. |
<evaluate> |
Evaluates an expression, optionally assigning it to a variable. |
<exception-handler> |
References a <bean> (through the bean attribute) that implements FlowExecutionExceptionHandler that should handle exceptions thrown in this state. |
<on-entry> |
Specifies actions (evaluations, setting of variables, and/or fragment render requests) to be performed upon entry to this state. |
<on-exit> |
Specifies actions (evaluations, setting of variables, and/or fragment render requests) to be performed as exiting this state. |
<render> |
Requests that the next view render a fragment of content. |
<secured> |
Used with Spring Security to restrict access to this state given the current user's security attributes. |
<set> |
Sets a variable in one of the flow's scopes. |
<transition> |
Defines a path from this state to another state based on an event or exception. May optionally execute one or more actions in the course of the transition. |
<action-state> Diagram
Defining a simple action state
As their name suggests, action states do something. The way to prescribe what action states do is through a nested <evaluate> element:
<action-state id=“addCustomer”>
<evaluate expression=“pizzaFlowActions.addCustomer(order.customer)” />
<transition to=“customerReady” />
</action-state>
The expression attribute is given an expression. Here the customer property of the flow-scoped order is passed into the addCustomer() method of a spring bean whose ID is “pizzaFlowActions”.
Transitioning on action evaluation
Ultimately, the value returned from the evaluation becomes the event ID that triggers a transition. For example, consider the following action state:
<action-state id=“cancelOrder”>
<evaluate expression=“pizzaFlowActions.cancelOrder(phoneNumber)” />
<transition to=“endState” on=“orderCancelled” />
<transition to=“cancelForm” on=“orderNotFound” />
</action-state>
In this case, if the cancelOrder() method returns “orderCancelled”, then the flow will transition to the state whose ID is “endState”. But if the method returns “orderNotFound”, then the flow transitions to “cancelForm” so that the user can specify a different phone number.
You can specify multiple evaluations within an action state. Be aware, however, that Spring Web Flow will evaluate each evaluation in order and stop when a transition trigger is fired. If the result of the first evaluation is an event that is handled by one of the transitions (including global transitions), then the remaining evaluations will never be evaluated.
Decision States
Decision states represent a binary branch in the flow based on the result of evaluating a boolean expression. Decision states are defined by the <decision-state> element.
<decision-state> Children
<decision-state> Child |
Description |
<attribute> |
Along with a nested <value> element, <attribute> declares a meta attribute to describe or annotate the state. |
<exception-handler> |
References a <bean> (through the bean attribute) that implements FlowExecutionExceptionHandler that should handle exceptions thrown in this state. |
<if> |
Specifies a boolean expression and a state to transition to if the expression evaluates to true. Optionally may specify a state to transition to if the expression evaluates to false. |
<on-entry> |
Specifies actions (evaluations, setting of variables, and/or fragment render requests) to be performed upon entry to this state. |
<on-exit> |
Specifies actions (evaluations, setting of variables, and/or fragment render requests) to be performed as exiting this state. |
<secured> |
Used with Spring Security to restrict access to this state given the current user's security attributes. |
<decision-state> Diagram
The <if> element is the heart of a decision state. It evaluates a boolean expression and then transitions to another state depending on whether or not the expression is true or false.
<decision-state id=“checkDeliveryArea”>
<if test=“pizzaFlowActions.isInDeliveryArea(customer.zipCode)” then=“addCustomer” else=“warnDeliveryUnavailable” />
</decision-state>
If the isInDeliveryArea() returns true, then the flow will transition to the “addCustomer” state. Otherwise, the flow will transition to the “warnDeliveryUnavailable” state.
End States
All flows must eventually come to an end. That's what the end state is for. End states are defined by the <end-state> element.
<end-state> Children
<end-state> Child |
Description |
<attribute> |
Along with a nested <value> element, <attribute> declares a meta attribute to describe or annotate the state. |
<exception-handler> |
References a <bean> (through the bean attribute) that implements FlowExecutionExceptionHandler that should handle exceptions thrown in this state. |
<on-entry> |
Specifies actions (evaluations, setting of variables, and/or fragment render requests) to be performed upon entry to this state. |
<output> |
Declares the output of a flow. Useful for passing state out of a subflow to the invoking flow. |
<secured> |
Used with Spring Security to restrict access to this state given the current user's security attributes. |
<end-state> Diagram
In it's simplest (and most common) form, an end state takes the following form:
<end-state id=“endState”/>
An end state that is defined like this simply ends the flow. Upon flow termination, the user will be taken to the beginning of the flow, starting a new instance of the flow.
Alternatively, the end state could navigate out of the flow to some other URL. All you need to do is specify the view attribute.
<end-state id=“endState” view=“/homePage.jsp” />
In this case, the flow will end and the user will be sent to the page whose URL is “/homePage.jsp” (relative to the context path).
If a Spring MVC view resolver is registered in the Spring application context, a logical view name can be used instead of an explicit view file path:
<end-state id=“endState” view=“homePage” />
{{ parent.title || parent.header.title}}
{{ parent.tldr }}
{{ parent.linkDescription }}
{{ parent.urlSource.name }}