• No results found

The five types of states

In document Spring (Page 161-165)

Enhancing Spring MVC applications with Web Flow

5.2 An overview of Spring Web Flow

5.2.2 The five types of states

</flow>

In addition to defining a flow, at

B

you explicitly define the enterSearchCriteria state as being the flow start state. Let’s talk more about states next.

5.2.2 The five types of states

Each box in figure 5.1 represents an individual step in the flow called a state. This is where something is displayed to the user, a decision is made, and a flow ends or some other action is taken. Like the “choose your own adventure” books we talked about earlier, flows must have a single start state but can contain one or many end states.

SWF defines five states, as shown in table 5.1.

Listing 5.1 Defining a flow

Figure 5.1 In this simpli-fied search flow, users start by entering search criteria and transition to a state where they can view their search results. The flow transitions to the end state after the user selects an item.

Explicitly defines start state

B

Missing from table 5.1 is the flow’s start state. The start state is a marker state that des-ignates another state (view, action, decision, end, subflow) defined in the flow as being the flow’s starting point. You defined an explicit start-state at

B

called enterSearchCriteria in listing 5.1. When start-state isn’t explicitly defined, the first state defined in the flow is assumed to be the start state. Let’s look at how each of these states is defined in SWF’s XML-based flow definition language.

VIEW STATE

The view state is used to either display or solicit information from the user and is defined using the view-state element in the flow definition XML file. In the simpli-fied search flow in figure 5.1, you use view states to interact with the end user by pre-senting a search form or viewing search results. In the following example, the logical view name is explicitly specified using the optional view attribute. If the view attribute isn’t specified, the view is given the same name as the state’s required id attribute along with a .jsp suffix. More on this later:

<view-state id="enterSearchCriteria" view="enterSearchCriteriaForm">

<transition on="search" to="viewSearchResults"/>

</view-state>

Although our focus in this chapter is on enhancing your existing Spring MVC applica-tion, SWF supports a number of view technologies. In addition to JSF, SWF can use any of the view technologies that Spring MVC supports out of the box. As of this writing, these are JSP, JSTL, Velocity, and XSLT.

When a view is rendered to the user, the flow pauses and waits for another event to occur. Users can continue flows by generating additional events by either clicking links or submitting forms containing event IDs. Event IDs can be specified as the value of the _eventId request parameter or directly in the request parameter’s name itself using the prefix _eventId_. In the following code snippet, both lines are equivalent.

_eventId=enterSearchCriteria _eventId_enterSearchCriteria Table 5.1 The five types of state in SWF

State type What it does

View The view state renders a view to the user and is used to either solicit information from or provide information to the user.

Action An action state is used when you want to perform some type of work and transition to another state based on its outcome.

Decision The decision state is similar to an action state but uses a convenient If…Then…Else statement to determine which state to transition to next.

End The end state represents the end of a flow. There may be one or many flow end states.

Subflow The subflow state starts another existing flow as a subflow and maps the subflow’s end states to transitions in the current flow.

To specify an event ID in a link, you need to include the event ID using one of the con-ventions appended to flowExecutionUrl. flowExecutionUrl is a variable that SWF provides that contains the context-relative URI for the current execution of the flow and some information about the current view state. The two lines in the following example are equivalent and show how to specify event IDs using links:

<a href="${flowExecutionUrl}&_eventId=enterSearchCriteria">

New Search</a>

<a href="${flowExecutionUrl}&_eventId_enterSearchCriteria">

New Search</a>

When the view is rendered, flowExecutionUrl contains the context-relative URI for the current flow execution and a request variable called execution. The link specified on the first line in the example may be resolved as

<a href="/myWebApp/myFlowId?execution=e1s1&_eventId=enterSearchCriteria">

New Search</a>

In the example, the value of the execution request variable is specified in the for-mat eXsY where e indicates the current instance of the flow myFlowId, which is denoted by X. The letter s indicates the current step that is being executed and is denoted by Y. Using the example you’re executing the first instance and first step of the flow with flowId myFlow. We’ll talk more about flow IDs and how they’re speci-fied and resolved later.

When using forms to capture user input, the event ID can be specified either in a hidden field or in the name of a submit button. The next code snippet provides an example of specifying the event ID using a hidden form field:

<form:form action="${flowExecutionUrl}" >

<input type="hidden" name="_eventId"

value="processSearchForm"/>

<input type="submit" value="Search"/>

</form:form>

Similar to the previous code, the following snippet provides an example of how to specify an event ID using a form submit button:

<form:form action="${flowExecutionUrl}" >

<input type="submit" name="_eventId_processSearchForm"

value="Search"/>

</form:form>

Notice how this example provides both the event ID and its value together using the underscore character

B

. The view state is unique in that it’s the only state where the currently executing flow pauses and waits for a user-generated event to occur. With the exception of the end state, other states continue the flow by evaluating events gen-erated in the state. Let’s look at the action state next.

Using a button name to specify the event ID

B

ACTION STATE

As the name suggests, the action state is where the application does work. You express the work to be done using an expression in an evaluate statement. Look at the fol-lowing example:

<action-state id="addVolunteer">

<evaluate expression="volunteerAction.addVolunteer(volunteer)"/>

<transition on="success" to="successView" />

<transition on="failure" to="failureView" />

</action-state>

At

B

, your expression calls the addVolunteer() method of a Spring-managed bean named volunteerAction, passing it a flow-scoped variable named volunteer. When the expression is evaluated, the value that volunteerAction returns becomes the event ID to transition to.

If you need to execute additional code, you can add evaluate elements. SWF will execute each expression in order until the outcome of the code being called matches a local or globally defined transition. We’ll discuss transitions in section 5.2.3.

DECISION STATE

A decision state provides a subset of the functionality of the action state mentioned earlier. Instead of checking the return value of one or more expressions to find a match to a local or global transition, the decision state evaluates a boolean expression and transitions to one of two states depending on the result. The addVolunteer code snippet is rewritten next as a decision state:

<decision-state id="addVolunteer">

<if test="volunteerAction.addVolunteer(volunteer)"

then="successView" else="failureView"/>

</decision-state>

Now that we’ve talked about how to start a flow, interact with users, and do work, let’s see how you end the flow.

END STATE

Once the flow transitions to an end state, it’s terminated:

<end-state id="myFlowEndState"/>

<end-state id="myFlowEndState" view="endOfFlowView”/>

In its simplest form, the flow ends at

B

. If a view is specified

C

, SWF renders the view in addition to ending the flow. As you’ll see next, if you’re ending a subflow, the end state’s id is used as an event to transition to in the parent flow.

SUBFLOW STATE

In general, it’s a good practice to break large, complex problems into smaller, more manageable pieces. Flows are no different. In SWF, the flow is a potentially reusable

Using Spring Expression Language (SpEL) to do work

B

Simplest form of flow’s end-state

B

Renders endOfFlowView view and ends flow

C

and self-contained component that is defined using states, transitions, flow data, inputs, and outputs. As shown in the following snippet, you use the subflow state in the top-level flow to call an existing flow as a subflow:

<subflow-state id="createdNewWidget" subflow="widget/createNew">

<input name="widget" value="widget"/>

<transition on="success" to "ourNextStateInParentFlow"/>

</subflow-state>

Here you are calling a subflow with the ID widget/createNew. You’re using the

<input> element to pass a widget object into the subflow for some type of configura-tion or modificaconfigura-tion. The example assumes that the subflow will transiconfigura-tion to an end state with the ID success. As we mentioned earlier, the ID of the subflow’s end state will be used as the event to transition to.

Now that we’ve discussed the five different types of states available in SWF, let’s turn our attention to transitions and see how you can use them to move from state to state.

In document Spring (Page 161-165)