Spring Web Flow
Spring Web Flow
SPRING FRAMEWORK
Dmitry Noskov Spring Web Flow 2.3
The Spring WEB stack
Portlet
specify path
<webflow:flow-location id=""
path="/hotels/booking/booking-flow.xml"/>
location pattern
<webflow:flow-location-pattern value="/**/*-flow.xml" />
listener
<webflow:flow-execution-listeners>
<webflow:listener ref="listener" criteria="*"/>
</webflow:flow-execution-listeners>
repository
<webflow:flow-execution-repository max-executions="5"
max-execution-snapshots="10"/>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
FlowHandlerAdapter
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor"/>
</bean>
…states…
</flow>
specific
<end-state id="bookingConfirmed">
<output name="booking" value="booking.id"/>
</end-state>
Conversation
Flow
Request
Flash
View
implementation
Spring EL
Unified EL
OGNL
view detection
by state id
by relative view id
by absolute view id
<bean id="mvc"
class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
<property name="viewResolvers" ref="tilesViewResolver"/>
<property name="useSpringBeanBinding" value="true" />
</bean>
hidden field
<input type="submit" value="Cancel" />
<input type="hidden" name="_eventId" value="cancel" />
submit button
<button type="submit" name="_eventId_proceed">Proceed</button>
<button type="submit" name="_eventId_cancel">Cancel</button>
<view-state id="enterBookingDetails"
view=""
model="booking"
parent=""
popup="true/false"
redirect="true/false" >
separate validator
public class BookingValidator {
public void validate(Booking b, ValidationContext c) {}
public void validateEnterBookingDetails(…) {}
}
state
on-entry
on-render (only for view)
on-exit
transition
action
public class CustomAction implements Action {
public Event execute(RequestContext context) {}
}
multi action
transitioning on evaluation
<action-state id="cancelBooking">
<evaluate expression="bookingService.cancelBooking()" />
<transition on="cancelled" to="endState"/>
<transition on="bookingNotFound" to="booking"/>
<transition on-exception="org.swf.AccessDenied" to="booking"/>
</action-state>
<action-state id="callTwoMethods">
<evaluate expression="service.methodOne()">
<attribute name="name" value="methodOne" />
</evaluate>
<evaluate expression="service.methodTwo()">
<attribute name="name" value="methodTwo" />
</evaluate>
<decision-state id="hasItems">
<if test="service.hasItems()"
then="checkItemsState"
else="end" />
</decision-state>
<transition on="cancel"
on-exception=""
to="cancel"
bind="true"
validate="true“
history="preserve/discard/invalidate"/>
<global-transitions>
<transition on="cancel" to="cancel" />
</global-transitions>
custom view
<end-state id="success"
view="externalRedirect:controller?result=success"/>
output
<end-state id="bookingConfirmed">
<output name="bookingId" value="booking.id" />
</end-state>
Bean
<bean name="hotels/booking" class="test.BookingFlowHandler"/>
client side
<script type="text/javascript"
src="<c:url value="/resources/dojo/dojo.js" />"></script>
<script type="text/javascript"
src="<c:url value="/resources/spring/Spring.js" />"></script>
<script type="text/javascript"
src="<c:url value="/resources/spring/Spring-Dojo.js"/>"></script>
<form:input path="creditCard"/>
<script type="text/javascript">
Spring.addDecoration(new Spring.ElementDecoration({
elementId : "creditCard",
widgetType : "dijit.form.ValidationTextBox",
widgetAttrs : {
required : true,
invalidMessage : "A 16-digit card number is required.",
regExp : "[0-9]{16}"
}
}));
</script>
<form:input path="checkoutDate"/>
<script type="text/javascript">
Spring.addDecoration(new Spring.ElementDecoration({
elementId : "checkoutDate",
widgetType : "dijit.form.DateTextBox",
widgetAttrs : {
datePattern : "MM-dd-yyyy",
required : true
}
}));
</script>
http://www.linkedin.com/in/noskovd
http://www.slideshare.net/analizator/presentations