Announcement Announcement Module
Collapse
No announcement yet.
is it possible to access flow scoped variables while binding? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • is it possible to access flow scoped variables while binding?

    Hello Everybody,

    I'm using Spring MVC and Spring WebFlow to develop a web application. On flow start, some actions store data in the flow scope. For example,

    Code:
    <on-start>
    	<evaluate expression="manager.getCollection()" result="flowScope.collection" />
    	...
    </on-start>
    Previous statement queries a database and initializes a collection of objects. This collection is dynamic and can change frequently. Users will be able to choose one element of this collection through a select HTML element. For example,

    Code:
    <form:select path="item">
    	<form:option value="">&nbsp;</form:option>
    	<c:forEach var="itemInCollection" items="${collection}">
    	<form:option value="${itemInCollection.id}">${itemInCollection.description}</form:option>
    	</c:forEach>
    </form:select>
    <form:errors path="item" element="p" />
    The whole flow includes several steps during which the collection doesn't change. So, there is not need to query the database once again, at least till the last step.

    The chosen item is bound to a property of a POJO.

    Code:
    <view-state id="enterDetails" model="command">
    	<binder>
    		<binding property="item" />
    		...
    	</binder>
    	...
    	<transition on="proceed" to="..." />
    	<transition on="cancel" to="cancel" bind="false" />
    </view-state>
    Code:
    public class Command extends java.io.Serializable {
    
    	...
    	
    	private Item item;
    	...
    }
    As you can note, users choose an ID of an item and send it to the server. At server side, the property to which user's choice should be bound is an object. That is, I need string to object conversion. Reading documentation at Spring side, I read that the most appropriate way to do so is using a formatter.

    Code:
    @Override
    public Item parse(String text, Locale locale) throws ParseException {
    	...
    }
    However, as far as I know in the parse method I can only access the user input, that is the item's id. Of course, I could query the database again using such id to get the Item but the application will be used by a big number of users and I wouldn't like to query the database so much. My question is: there is a way to access the collection stored at the flow scope from the formatter? If I am able to access such collection, there is no need to query the database again at least till the last step of the flow.

    Thanks in advance.

    Best wishes,
    Sandy

  • #2
    Hello,

    I know this is an old post but I'll reply myself in order to help other people with the same problem.

    It achieved it doing the following:

    1. I initialized flow-scoped variables on flow starting:

    Code:
    <on-start>
    	<evaluate expression="manager.getCollection()" result="flowScope.collection" />
            ...
    </on-start>
    2. Since users choose item IDs at client side and then send them to the server. At server side, these IDs should be mapped to the corresponding object. That is, we need to make use of Spring's type conversion mechanism. I configured it as follows:

    Code:
    <!-- instantiates the formatter -->
    <bean id="applicationConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean”>
    	    <property name="formatters">
    	        <list>
    	            <bean class="com.acme.exampleapp.formatters.ItemFormatter"/>
    	        </list>
    	    </property>
    	</bean>
    
    <!-- makes Spring MVC aware of the formatter -->
    <mvc:annotation-driven conversion-service="applicationConversionService" />
    
    <!-- passes conversion service from Spring MVC to Spring Web Flow -->
    <bean id="defaultConversionService" class="org.springframework.binding.convert.service.DefaultConversionService">
        	<constructor-arg ref="applicationConversionService"/>
        </bean>
    
    <!-- makes Spring Web Flow aware of the formatter -->
    <webflow:flow-builder-services id="flowBuilderServices" … conversion-service="defaultConversionService" />
    3. Finally, my formatter class looks as follows:

    Code:
    public Item parse(String text, Locale locale) throws ParseException {
    		RequestContext requestContext = RequestContextHolder.getRequestContext();
    		Map<String, Item> items = (Map<String, Item>) requestContext.getFlowScope().get("collection");
    		return items.get(text);
    	}
    I hope this post helps somebody else.

    Best wishes,
    Sandy Pérez González
    IT Consultant,
    Indaba Consultores S.L.
    http://www.indaba.es/

    Comment

    Working...
    X