FlowInputMappingException when mapping of object in Spring Webflow

1.5k Views Asked by At

I am trying to follow the code for Spring Webflow from 'Spring in Action'. However, when I tried to run the application, I got the following error:

org.springframework.webflow.engine.FlowInputMappingException: Errors occurred during input mapping on startup of the 'pizza' flow; errors = [[RequiredError@13cb4078 mapping = order -> flowScope.order, code = 'required', error = true, errorCause = [null], originalValue = [null], mappedValue = [null]]]

I believe the line that instantiates the order object in the following flow xml is responsible for the exception:

<var name="order" class="com.mycompany.pizza.domain.Order" />
    <subflow-state id="customer" subflow="customer-flow">
        <input name="order" value="order"/>
        <transition on="customerReady" to="buildOrder" />
    </subflow-state>

My subflow xml looks like this:

<view-state id="welcome">
    <transition on="phoneEntered" to="lookupCustomer" />
</view-state>

<action-state id="lookupCustomer">
    <evaluate result="order.customer"
        expression="pizzaFlowActions.lookupCustomer(requestParameters.phoneNumber)" />
    <transition to="registrationForm"
        on-exception="com.mycompany.pizza.service.CustomerNotFoundException" />
    <transition to="customerReady" />
</action-state>

Hope there's someone who could point me at the right direction. Thanks!

1

There are 1 best solutions below

10
On

The error is saying you are REQUIRED to pass a NOT NULL input param/obj "order" to your subflow and you are passing a null value in the order input. So if it is not provided it will throw the exception you see. At the top of your subflow should look something like this:

<input name="order" required="true" type="com.mycompany.pizza.domain.Order"/>

That being said, generally I think when passing pojos between flows/subflows it is good practice to be very explicit and fill out the 'type' attribute in both input tags on the caller of the subflow and the subflow itself and to fill out the scope prefix for the value attribute (e.g flowScope.order)

Moreover, I think your problem is that the <var> tag is NOT initializing your Order pojo that is why it is null it is the equiv of:

Order order = null;

You should explicitly set flowScope.order via a new operator or a factory-method call using the 'set' tag inside an 'on-start' tag in beginning of your parent flow. Something like this:

<on-start>
       <set name="flowScope.order" value="new com.mycompany.pizza.domain.Order()"/>
        <!-- for development purposes... assuming you are using log4j grab the logger and check that order is in fact NOT null -->
        <evaluate expression="T(org.apache.log4j.Logger).getLogger('someLogger').info(flowScope.order)"/>
</on-start>

and then (still inside your parent flow) change your subflow call to look like this:

<subflow-state id="customer" subflow="customer-flow">
    <input name="order" value="flowScope.order" type="com.mycompany.pizza.domain.Order"/>
    <transition on="customerReady" to="buildOrder" />
</subflow-state>

and... Make sure you also fill out the type attribute inside the input tag of your subflow.xml for order like so:

<input name="order" required="true" type="com.mycompany.pizza.domain.Order"/>