Sunday 2 September 2007

Tip: Output a success message in a subflow in Spring Web Flow

In Ajax applications is common output a success or error message (like Google Mail interface). With Spring Web Flow I can define subflows to do commons things and reuse parts of the application but if I want to output a success message, the natural way it's to define a view state.

This tip shows other way to output a message.

I have a subflow to add a new company.

<start-state idref="enterCompanyData"/>

<view-state id="enterCompanyData" view="people/ajax/company_add">
<render-actions>
<action bean="formAction" method="setupForm" />
</render-actions>
<transition on="submit" to="saveCompany">
<action bean="formAction" method="bindAndValidate" />
</transition>
</view-state>

<action-state id="saveCompany">
<bean-action bean="companyManager" method="save">
<method-arguments>
<argument expression="flowScope.company" />
</method-arguments>
</bean-action>
<transition on="success" to="finish">
<set attribute="message" value="'company.addCompany.success'" />
</transition>
</action-state>

<end-state id="finish">
<output-mapper>
<mapping source="requestScope.message" target="message" />
</output-mapper>
</end-state>


When I save a company in the action state "saveCompany", I set an atttibute named "message" with a value of String 'company.addCompany.success' (with a single quotes, otherwise the expression language thinks that is a Java Bean), this value is a key for i18n.

In the end state "finish", I have to map the attribute message to the output.

Next, in the root flow, I have to capture the message and put in the flash scope.

<subflow-state id="companyAdd" flow="company-add-flow"> 
<attribute-mapper>
<output-mapper>
<mapping source="message" target="flashScope.message"/>
</output-mapper>
</attribute-mapper>
<transition on="finish" to="companyList" />
</subflow-state>


Putting the message in the flash scope, allow to view the message until next event.

And the last step is show the message in JSP, you have to include this code, in all view states.

<c:if test="${not empty message}">
<fmt:message key="${message}"/>
</c:if>

No comments: