Spring Webflow : how do I pass an attribute from one flow to another during a transition?

Nick Foote picture Nick Foote · Jan 5, 2011 · Viewed 30.6k times · Source

I have an action-state that evaluates an expression and then transitions to various other states depending on the result. One of the result states is a subflow-state that hands control to another flow, example;

<action-state id="doWork">
    <evaluate expression="someAction.doWork(someInput)" />
 <transition on="WORKSUCCESS" to="workSuccess" />
 <transition on="WORKFAIL" to="fixFail" />
</action-state>

<subflow-state id="fixFail" subflow="someOtherPlace/someOtherWorkToFixFail">
    <input name="someNumber" value="1" type="java.lang.Integer" />
    <transition on="finish" to="workSuccess" />
</subflow-state>

As you can see I can pass an input into the subflow via the input tag but my question is how can I specify and pass additional inputs that I want present if and only if the subflow-state is being called from the transition WORKFAIL? Assume the subflow-state "fixFail" can be called from other action-states.

I've tried things similar to the following with no effect;

<action-state id="doWork">
    <evaluate expression="someAction.doWork(someInput)" />
 <transition on="WORKSUCCESS" to="workSuccess" />
 <transition on="WORKFAIL" to="fixFail">
            <attribute name="newInput" value="3000" type="java.lang.Integer" />
    </transition>
</action-state>

<subflow-state id="fixFail" subflow="someOtherPlace/someOtherWorkToFixFail">
    <input name="someNumber" value="1" type="java.lang.Integer" />
    <input name="someNumber2" value="flowScope.newInput" type="java.lang.Integer" />
    <transition on="finish" to="workSuccess" />
</subflow-state>

Answer

John Vint picture John Vint · Jan 5, 2011

There are three ways you can do this. You can do it through the conversation, session or as attributes passed in.

  • ConversationScope: If a field is in the conversationScope the field is visible anywhere in that specific flow as well as that flow's subflows (and their transitions)

  • SessionScope: (Probably not what you want) Is visible to all flows and
    their subflows

Finally you can pass the field as an attribute into the subflow state for example

<subflow-state id="fixFail" subflow="someOtherPlace/someOtherWorkToFixFail">
    <input name="someNumber" value="1" type="java.lang.Integer" />
    <input name="someNumber2" value="flowScope.newInput" type="java.lang.Integer" />
    <transition on="finish" to="workSuccess" />
</subflow-state>

In your subflow's xml

<?xml version="1.0" encoding="UTF-8"?>
<flow>
    <input name="someNumber"/>
    <input name="someNumber2"/>
    ...
</flow>

In this example someNumber and someNumber two are passed in as attributes to your subflow. In which you can evaluate them as ${someNumber}

Edit:

This is to address your comment question. If you wanted to set a variable in the conversation scope on a specific transition you can do:

<transition on="WORKFAIL" to="fixFail" >
  <set name="conversationScope.someVariable" value="Hello World"/>
</transition>

Then in your jsp

${someVariable}  <!-- This will print out 'Hello World' -->