March 02, 2010

Configuring View Resolver for Spring web flow

From the previous post, we learned how to setup spring web flow application. With the minimal set up there are few downsides. One of it is the usage default view revolver. In this post, we are going to see how to configure view resolver.

The major concern with the minimal setup is that, both flow definition XML file and the views should be in the same directory. Also, the default view resolver expect a JSP or JSPX page. If you look at the flow definition in the previous post, you will see that, we have provided the complete filename for the view attributes. What if I want to organize my views in different folders like MVC applications?

To configure view resolver, you need to "what is" and "how to configure" flow builder service. FlowBuilderServices class simply hold the services used by flow builder. When configuring these services, we need to provide concrete service implementations. We will configure a view resolver using the InternalResourceViewResolver. I am also using the JSTL view class and here is my bean definition:


<bean id="viewResolver" 
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" 
value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
Well, that's pretty normal for a Spring MVC application. Notice that I have defined a prefix and all my JSP files will reside under WEB-INF/jsp/ folder. Next is the define the flow builder service. This is defined using flow-builder-services tag as shown below:
<flow:flow-builder-services id="flowBuilderService" view-factory-creator="viewFactoryCreator"/>
Since we are configuring the view resolver for our application, we need to provide reference of view-factory-creator. View factory creator is an instance of MvcViewFactoryCreator class. The class detects whether it is running in a Servlet or Portlet MVC environment, and returns instances of the default view factory implementation for that environment. Here is how the bean is configured:
<bean id="viewFactoryCreator" 
class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">  
<property name="viewResolvers">  
<list>  
<ref bean="viewResolver"/>  
</list>  
</property>  
</bean>
We will use our previously configured viewResolver to set the viewResolvers propertyof the MvcViewFactoryCreator class.

To sum up the configurations:
<flow:flow-registry id="flowRegistry" 
flow-builder-services="flowBuilderService">
<flow:flow-location id="loginform" 
path="/WEB-INF/flows/simple-flow.xml" />
</flow:flow-registry>
<flow:flow-builder-services 
id="flowBuilderService" 
view-factory-creator="viewFactoryCreator"/>
<bean id="viewFactoryCreator" 
class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">  
<property name="viewResolvers">  
<list>  
<ref bean="viewResolver"/>  
</list>  
</property>  
</bean>  
<bean id="viewResolver" 
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" 
value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

Hope this post help people who are trying out Spring web flow.

1 comment :

Andy said...

Very nice post!

I would like to use SWF and JSF (I'm using JSF-Tags in my JSP) so I configure it, in dependence on your post. But now, if I create a button in my view like "h:commandButton action=test value=test" the site is only refreshed and the transition-definition is ignored. Can you help me with this problem?