Tuesday, June 17, 2008

Simple Spring Web Flow 2.0 Example Ready

I finally have a very Simple Spring Web Flow 2.0 example ready. It's building on the Spring MVC annotation-based Controller and Spring Security 2.0 examples I did recently. I'm actually still working on a more advanced example showing how to have a subflow for Person addresses, but I wanted to post what was working so far and it might be less confusing to people as they're getting started since there is less going on.

There is an error currently when leaving the flow from a save and a cancel. It says 'Could not complete request' and is an IllegalStateException. It seems to be some problem with a redirect, but everything works fine.

The more advanced subflow example just needs to have messages and validation added to it., and I might try to switch it from using a Hibernate DAO class to using Spring Web Flow's built in JPA persistence hooks. It really took a long time to get the subflow working. I had to try a lot of different things to get the address id passed into the subflow. Spring Web Flow is really nice, but there could be a lot more documentation and examples illustrating things like this. I couldn't find any concrete examples doing this for Spring Web Flow 2.0.




The person flow uses Spring Security to limit the flow to a 'ROLE_USER'. Based on whether or not an id attribute is available, the decision-state element will forward to a 'createPerson' or 'editPerson' action-state. The 'createPerson' one uses El to create a new Person instance for the form to bind to using a method on the person controller. The edit uses the person DAO instance to look up the person record. They both forward to the 'personForm' where you can save or cancel, and save uses the person DAO to save the person instance. The person instance is automatically bound by specifying the model attribute as 'person' on the view-state. Both cancel and save then populate the latest search results and forward to the search page.

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/webflow
                          http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">

    <secured attributes="ROLE_USER" />

    <input name="id" />

    <decision-state id="createOrEdit">
        <if test="id == null" then="createPerson" else="editPerson" />
    </decision-state>

    <action-state id="createPerson">
        <evaluate expression="personController.newPerson()"
                  result="flowScope.person" />
        <transition to="personForm" />
    </action-state>

    <action-state id="editPerson">
        <evaluate expression="personDao.findPersonById(id)"
            result="flowScope.person" />
        <transition to="personForm" />
    </action-state>

    <view-state id="personForm" model="person" view="/person/form">
        <transition on="save" to="savePerson">
            <evaluate expression="personDao.save(person)" />

            <evaluate expression="personDao.findPersons()"
                      result="flowScope.persons" />
        </transition>
        <transition on="cancel" to="cancelPerson" bind="false">
            <evaluate expression="personDao.findPersons()"
                      result="flowScope.persons" />
        </transition>
    </view-state>

    <end-state id="savePerson" view="/person/search" />

    <end-state id="cancelPerson" view="/person/search" />

</flow>

No comments: