Developing Spring Web Flow 2 Application part 2 – Web Flow Setup

As part of “Developing Spring Web Flow 2 Application” series, this post shows the following features:

  • Spring Web Flow Setup
  • Spring MVC Integration




I. Web Flow setup

To setup Spring Web Flow, there are few things to configure.

  • FlowRegistry
  • FlowExecutor



FlowRegistry

FlowRegistry is used to register flow definition.

<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices" > <webflow:flow-location path="/WEB-INF/flows/home/home.xml" /> ... </webflow:flow-registry>



The flow-location element is used to specify paths to flow definition files.

(from: Spring Web Flow Reference Guide)
By default, flows will be assigned registry identifiers equal to their filenames minus the file extension, unless a registry base path is defined.




In our case, flow identifier for the flow added in the registry is ‘home’. In addition to flow-location element, we can also choose flow-location-pattern and/or base-path elements as an alternative ways to specify flow definition file location.

We can further customize the services and settings used to build flows in a flow registry by configuring a flowBuilderServices.

With a flowBuilderServices defined, we can configure services such as conversion-service, expression-parser and view-factory-creator. For example, we can configure a view-factory-creator to customize the viewFactoryCreator used by the Web Flow.

<webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="mvcViewFactoryCreator" /> <bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator"> <property name="viewResolvers" ref="viewResolver"/> </bean>



The mvcViewFactoryCreator bean is the factory that tells how the Spring MVC view system is used inside Spring Web Flow. We can configure a viewResolver such as InternalResourceViewResolver for this factory like what we usually do in a Spring MVC application.




FlowExecutor

Flow Executor is where execution of flows take place. We can use flow-execution-listeners element to register listeners such as security listener or persistence listener. See part 4 and part 5 of this series for an example of configuring these listeners.

<webflow:flow-executor id="flowExecutor"> <webflow:flow-execution-listeners> <webflow:listener ref="securityFlowExecutionListener" /> <webflow:listener ref="jpaFlowExecutionListener" /> </webflow:flow-execution-listeners> </webflow:flow-executor>



II. Spring MVC Integration

Same as any other Spring MVC application, the first step to integrate Spring MVC and Spring Web Flow is to configure a DispatcherServlet in the web.xml file.

<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value> ... </param-value> </context-param> <servlet> <servlet-name>shopping</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>0</load-on-startup> </servlet>         <servlet-mapping> <servlet-name>shopping</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>     <servlet-mapping> <servlet-name>shopping</servlet-name> <url-pattern>/account/*</url-pattern> </servlet-mapping>



Then, we are going to configure the following beans to make Spring MVC and Spring Web Flow work together.

  • FlowHandlerAdapter
  • FlowHandlerMapping



FlowHandlerAdapter

As DispatcherServlet maps requests for resources to handlers, to enable DispatcherServlet to dispatch requests to flows we need to configure a FlowHandlerAdapter to enable flow handling within Spring MVC.

<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter"> <property name="flowExecutor" ref="flowExecutor"/> </bean>



FlowHandlerMapping

Then, we configure a FlowHandlerMapping bean to map resources to flows.

<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping"> <property name="order" value="0" /> <property name="flowRegistry" ref="flowRegistry" /> </bean>



(from: Spring Web Flow Reference Guide)
Configuring this mapping allows the Dispatcher to map application resource paths to flows in a flow registry.




III. Plain Controller

In addition to letting flow handler to handle flow requests, there are situations where we need our old plain Controller to serve non-flow requests like what we do in a Spring MVC application.

To enable plain Controller in Spring Web Flow, we need to configure a SimpleControllerHandlerAdapter.

<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />



Our plain old controller class is very simple, based on the request URL, extract the view name from it and return a ModelAndView object with the view name.

package com.shoppingcart.web; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.stereotype.Controller; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController; @Controller public class HomeController extends AbstractController { private static Logger logger = Logger.getLogger(HomeController.class); @Override protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { ... String contextPath = request.getContextPath(); String requestURI = request.getRequestURI(); String view = requestURI.substring(contextPath.length() + 1); return new ModelAndView(view); } }



For Spring to to auto-detect this controller with the @Controller annotation, we need to enable Spring’s component scanning feature through the component-scan element.

<context:component-scan base-package="com.shoppingcart" />



Finally, we configure a HandlerMapping bean for the request resource mapping and a ViewResolver bean for view name/jsp page mapping used by both controller and MvcViewFactoryCreator.

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" > <property name="mappings"> <props> <prop key="/login">homeController</prop> <prop key="/logoutSuccess">homeController</prop> </props> </property> <property name="order" value="1" /> </bean>           <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> <property name="order" value="1" /> </bean>



Advertisements
Developing Spring Web Flow 2 Application part 2 – Web Flow Setup

4 thoughts on “Developing Spring Web Flow 2 Application part 2 – Web Flow Setup

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s