Introduction to Spring Web Flow
by, 11-29-2011 at 02:49 AM (2611 Views)
When you are developing an user interaction for an application, one of the most challenging aspects is to define a proper narrative for the behavior of the application so that the user can get into a flow while using the application. Sometimes it is necessary to step a user through a process, such as ordering a plane ticket. This is called a flowed application. Now is a possible to use any web framework, such as Struts or Java Server Faces, in order to do this. Unfortunately none of them properly separate the flow from the implementation in such a way that elements involved in the flow could be reused. It is for this reason, that the team that developed Spring, decided to develop an extension to Spring MVC called Spring Web Flow. I will introduce you to its features in this article.
Spring Web Flow is a web framework that enables you to develop a user interaction based on elements following a prescribed flow. All requests to a particular flow will first go through Spring’s DispatcherServlet. Then a handful of beans specifically made for Spring Web Flow are configured in the Spring application context to handle the flow request and execute the flow. There are a number of the web flow beans that are declared using elements in the Spring Web Flow’s XML namespace. The namespace must be added to the XML file:
How does Spring Web Flow WorkJava Code:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:flow="http://www.springframework.org/schema/webflow-config" xsi:schemaLocation="http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/ ̄ spring-webflow-config-2.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
Spring Web Flow is basically composed of a set of states. In each state it will either be displaying a view or executing an action. The transition of the flow from one state to another is triggered by an event. This will continue until the flow has completed or entered the end-state. The key web flow states are:
- Start-state - when a flow is created the initial state of the flow is defined by the start-state attribute in the web flow.
- Action-state - where it executes an action and returns a logical result on its completion. This will determine which flow will be transitioned.
- View-state - pauses the flow and returns the control to the user and the flow is resumed on the user event. This resumes the flow and triggers the transition to the state depending on the user input or decision.
- Decision-state - is used to determine the next state dynamically or at runtime depending on for example, the user being authenticated.
- Subflow-state - is used to represent independent flows not dependent on the main flow. A subflow is a child of main flow (parent flow). When child flow is active, the parent flow is suspended. Only when the child flow completes is the parent show re-enabled.
- End-state - signifies the end of the flow. When a flow reaches the end-state the active flow session is terminated. If the end-state of the root flow is entered the resources associated with it are cleaned up automatically.
How do I configure web glow beans:
1. Configure the Flow Executor
The flow executor drives the execution of a flow. As the user enters a flow, the flow executor creates and launches an instance of the flow execution for that user. The flow pauses when a view is presented to the user. The flow executor will then resume once the flow has taken some action.
The <flow:flow-executor> element creates a flow executor in Spring:
Now, the flow executor is not responsible for loading flow definitions. That is the responsibility of a flow registry which is referred to by its ID: flowRegistry.1Java Code:<flow:flow-executor id="flowExecutor" flow-registry="flowRegistry" />
2. Configuring a Flow Registry
A flow registry’s job is to load flow definitions and make them available to the flow executor. You configure a flow registry in the Spring configuration with the <flow:flow-registry> element in the following manner:
In this configuration, the flow registry will look for flow definitions under the /WEB-INF/flows directory, as specified in the base-path attribute. From the <flow:flow-location-pattern> element, any XML file whose name ends with -flow.xml will be considered a flow definition. Spring uses their IDs to refer to each flow. When you are using a flow location pattern, the path to the flow definition file relative to the base path will be used as the flow’s ID. In the <flow:flow-location-pattern> element, the flow ID will be the directory path relative to the base-path. Otherwise, you could leave the base-path attribute off and explicitly identify the flow definition file’s location as shown below:Java Code:<flow:flow-registry id="flowRegistry" base-path="/WEB-INF/flows"> <flow:flow-location-pattern value="*-flow.xml" /> </flow:flow-registry>
Here, the <flow:flow-location> element is used instead of <flow:flow-location- pattern>. The path attribute directly points at the /WEB-INF/flows/springexamples.xml file as the flow definition. When configured this way, the flow’s ID is derived from the base name of the flow definition file; springexamples in this case. If you’d like to be even more explicit about the flow’s ID, then you can set it with the id attribute of the <flow:flow-location> element. For example, to specify cars as the flow’s ID, configure the <flow:flow-location> like this:Java Code:<flow:flow-registry id="flowRegistry"> <flow:flow-location path="/WEB-INF/flows/springexamples.xml" /> </flow:flow-registry>
3. Handling Flow RequestsJava Code:<flow:flow-registry id="flowRegistry"> <flow:flow-location id="car" path="/WEB-INF/flows/springexamples.xml" /> </flow:flow-registry>
The DispatcherServlet typically dispatches requests to controllers. But for flows, Spring requires that you use a FlowHandlerMapping to help DispatcherServlet to determine that it should send flow requests to Spring Web Flow. The FlowHandlerMapping is configured in the Spring application context:
Note the FlowHandlerMapping is wired with a reference to the flow registry so it knows when a request’s URL maps to a flow. So if we have a flow whose ID is car, then FlowHandlerMapping will know to map a request to that flow if the request’s URL pattern is /car relative to its application context.Java Code:<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping"> <property name="flowRegistry" ref="flowRegistry" /> </bean>
The FlowHandlerAdapter responsibility is to answer the call and the FlowHandlerMapping’s job is to direct flow requests to Spring Web Flow. A FlowHandlerAdapter is equivalent to a Spring MVC controller in that it handles requests coming in for a flow and processes those requests. The FlowHandlerAdapter is wired as a Spring bean:
The handler adapter is the bridge between DispatcherServlet and Spring Web Flow. It’s responsibility is to handles flow requests as well as to change the flow based on those requests. In the listing above it’s wired with a reference to the flow executor. The handler adapter will execute the flows that it handles requests for. Now that all of the beans and components are configured in order for Spring Web Flow to work. The next thing to do is to actually define a flow. In another article, we will look at the elements that are put together to make up a flow.Java Code:<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter"> <property name="flowExecutor" ref="flowExecutor" /> </bean>