Spring Webflow

From Kb

Jump to: navigation, search

Contact Article Author | Blog of Article Author | FirstPartners.net Home | LinkedIn profile of Author

Contents

See Also

Online Links

Spring Webflow Quickstart

  1. Add Webflow Jars to Classpath
  2. Create Spring Webflow.xml (this is a separate file from the Normal SpringAppContext.xml). This defines Start, Transition and End States (and related Actions)
    1. Use beans (Spring MVC Actions) defined in another file using <import resource="name-of-file-to-import.xml"/>
  3. Create FormBean extending FormAction (as referenced in 2)
  4. Register Flow in (normal) Spring Config file -SpringAppContext.xml (normally using XmlFlowRegistryFactoryBean)
  5. Setup your normal web framework(e.g. Struts or Spring MVC)
    1. For Spring MVC this means setup beans to handle dispatch url-java (FlowController) and a ViewResolver (what JSP is displayed at the end).
  6. Create the JSP that the ViewResolver will redirect.
  7. Webflows are typically accessed in the format : myApp.htm?_flowId=myFlow
    • where myApp.htm is mapped to the Spring Webflow resolver

Spring Webflow Notes

  • PropertyEditorRegistrar
    • Allows us to fine tune the formatting of dates - specified as param (via standard Spring Config) so can be reused across multiple controllers.
  • Standard url to kick off flow is in norm flowController?_flowId=name-of-my-flow
    • where flowcontroller is bean (in spring servlet config file) that maps to instance of org.springframework.webflow.executor.mvc.FlowController. This is configured as follows
<!-- Define the base url - so that we call the url above, spring MVC knows to route request to our flow controller-->
	<bean name="/flowController" class="org.springframework.webflow.executor.mvc.FlowController">
		<property name="flowExecutor" ref="flowExecutor"/>
	</bean>
 
        <!-- The actual bean that 'executes our flow'. This one also has a (security) listener defined. 
	<flow:executor id="flowExecutor" registry-ref="flowRegistry" repository-type="singlekey">

		<flow:execution-listeners>
			<flow:listener ref="authorizationFlowListener"/>
		</flow:execution-listeners>
	</flow:executor>
 
        <!-- Registry that Loads all flows - all files ending in -flow.xml -->
	<flow:registry id="flowRegistry">
		<flow:location path="/WEB-INF/flows/**/*-flow.xml" />
	</flow:registry>


What Webflow requires in the view (JSP)

  • From Page 87 of the Spring Webflow pdf
The priceAndItemCountForm.jsp page collects a price and an itemCount using Spring 2.0 form input tags
binding form fields to properties in the form backing object "sale". When pressed, the submit button
"_eventId_submit" causes a web flow transition for an event with the id of "submit" to the view state
"enterCategory". Prior to transitioning the formAction's bindAndValidate method is called to perform binding
and (partial) validation using the validatePriceAndItemCount method of the validator object.
  • The Event ID can either be a field on the form , and set by the Spring tags , or Javascript
<script language="javaScript">	
function submitForm(eventName)
{
	document.myForm._eventId.value = eventName;
	window.alert("Set _eventId for webflow to:"+document.myform._eventId.value);
	document.myForm.submit();
}
</script>
  • for the above sample , use the Spring:Form tags (for display) and Tie the Javascript to the Spring Button Event as follows (note the button on the form)
<!-- Spring MVC tag for form - commandName is the Java Bean that the values will be bound to-->
<form:form commandName="mySpringBeanName" name="myForm" method="post">
 
<!-- Hidden field for Spring webflow -->
<input type="hidden" name="_eventId" />
 
<!-- Other Fields-->
<!-- Path refers to some bean available in the Session / Flow. It does not include the form bean (as it is defined by the form tag). The samples below would ties to myFormBean.getNameOfVarOnMySpringBean().getValueWithGetAndSetMethodsOnVar() etc -->
<form:label id='someLabel' path="nameOfVarOnMySpringBean.someSubGetMethod"/>
<form:input id='someInput' path="nameOfVarOnMySpringBean.valueWithGetAndSetMethodsOnVar"/>
 
<!-- Button to trigger Spring webflow event -->
<button name="OkButton" value="Ok" title="Ok" id="_eventId_OK" onclick='javascript:submitForm("OK")'>OK</button>
 
</form:form>

Spring Webflow , Context and Session

  1. Config files (as loaded by above) map request to correct action e.g.
    1. See samples in section 6 of the Spring Webflow docs
  2. Signature of method that gets called
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
...
public Event someBusinessmethod(RequestContext context) throws Exception {}
...

Starting and Ending Subflows

  • Subflows are just 1 flow called from another. Webflows are independent and resuable. Think of call to subflow like call to method.
  • Flows are instances of org.springframework.webflow.engine.Flow
  • Flows can have input and output parameters
  • Use a SubflowState on the mainflow to kick of an instance of the (sub)flow - which is just a flow in itself.
  • When the subflow is finished, transition (in the subflow) to the end state, specifying no view. You'll probably need some javascript (see submit form javascript to do a window.close as well). Sample of end transition:
    • <end-state id="end"/>
<!-- Taken from the Spring Webflow PDF Sample, but with extra comments -->
<!-- Shipping is the name of the subflow (defined elsewhere)
<subflow-state id="enterShippingDetails" flow="shipping">

 
 
     <attribute-mapper>
 
          <!-- The Params we pass into the subflow. In case, it is the value of order.shipping from the main flow -->  
          <input-mapper>
               <mapping source="flowScope.order.shipping" target="shipping"/>
          </input-mapper>
 
          <!-- The Params we pass out of the subflow. In case, copy the value of order.shipping from the subflow to the mainflow --> 
          <output-mapper>
                <output-attribute name="shipping"/>
          </output-mapper>
 
     </attribute-mapper>
 
     <!-- The target (on the main flow) that we transition to when the subflow is done -->
     <transition on="finish" to="placeOrder"/>
 
</subflow-state>
  • Instead of the XML , you could equally use the OrderFlowBuilder API.
Personal tools