Вы находитесь на странице: 1из 50

M anaging W eb Conversations

w ith Spring W eb Flow


Keith Donald
http://www.springframework.com
keith@interface21.com
Agenda

 History
 Motivation
 Positioning
 Architecture
 Walkthrough
 Issues and Solutions
 Conclusion

 Goals:
 Understand Spring’s position in the web
framework space
 See the value of Spring Web Flow (SWF) in action
H istory – From Spring’s
Perspective
2000 2003 2004 Fall 2005

Struts Spring MVC Ervacon Unified Spring Web Stack:


Web Flows Servlet MVC, Portlet MVC,
Web Flow (SWF)
 Today, Struts is still the web framework
leader in terms of existing application
deployments
 Despite well-known limitations

 Despite many challengers

 The pragmatic majority is still waiting for


the next dominant paradigm to emerge
Spring’s W eb Stack M otivation
 To address the Struts pain points that are
hurting our customers
 Spring MVC provides a better architecture
without a high level of paradigm shock
 To meet customer demand in places
where it is clear Struts does not provide a
solution
 Spring has embarked into new territory
 With its customers charting the course
 Extracting new “whole products” to form a
complete web stack
Product Positioning
 A unified web stack, offering a one stop
shop for agile web application
development
 Respecting the existing Struts install base
 Spring will continue to provide first class
Struts support
 Built from a set of modular, best-of-breed
components
 That can be integrated with other
technologies where customers demand
• e.g. SWF is usable by JSF customers as a
NavigationHandler
Spring Clarity
Spring Web Stack

Servlet MVC Portlet MVC

Web Flow Remoting

Spring Middleware Stack


(IOC, AOP, TX, DAO, ORM, MGMT, JCA)

Spring AgileDev
(Build, Test, Deploy)

Each product in the stack integrates a number of components


• e.g. Spring MVC supports JSP, Freemarker, PDF, Jasper, and Excel views
• Emerging web components include Valang for validation and DWR for AJAX
M arket Expectations
 The current fragmentation in the web
framework market will subside
 Consolidation will happen
 It’s already starting to

 Spring will be a major player in the post-


shakeout, offering:
 Maturity and synergy across the full stack

 Low switching costs

 Breakthrough technology

 Professional support
Breakthrough Technology
Architecture
 By example
 Take a simple use case:
 A wizard for a phone operator to use to
sell items to customers
 Characteristics:
 An “application transaction” that spans
several steps
 Some steps solicit user input
 Some steps are decision points
 Some steps perform calculations
 Navigation from step-to-step is controlled
H ow w ould you do this today w ith
Struts?
1. Create a session-scoped ActionForm to
hold the wizard form data
2. Define a JSP for each step
3. Define an Action for each step
4. Expose each Action at a request URL
5. Have the form rendered by the JSP
submit to that URL
6. At the end, delegate to a business
service to commit the transaction
W hat this looks like

/step1.do
storeForm

page1
Controller 1 HTTP
Session

/step2.do
updateForm

page2
Controller 2

/lastStep.do Business
processTx Service
confirmationPage
Controller 3
Issues w ith this approach
 Request centric: no concept of an ongoing
conversation or flow
 Brittle dependency on request URLs
 Manual state management
 Odd new window behavior
 Proper back button behavior is difficult
 “Loose” controlled navigation
 Difficult to observe process lifecycle
 Controller and command logic are coupled
 Heavily tied to HTTP
Consequences
 Many lines of custom code are
written to address these issues
 As an application grows more complex
maintainability breaks down
 Fundamentally, something is missing
 Traditional approaches today lack a key
abstraction: the Flow
 A Flow is typically longer than a single
request but shorter than a session
 It is a conversation!
Flow Conversation Analogy
Keith (Oslo, Norway)

Friend: Hello?
Keith: Hi Friend!
Friend: Hi Keith! So, have you
decided to just stay in Europe
for good now?
Keith: Life IS great here, huh?
 Friend (Melbourne, Florida)
Keith: Gotta go, bye!
W hat the SW F approach looks
like
start “sell Item”

firstPage

store
submit
Flow
nextPage Execution
Storage
load

submit

confirmationPage “Sell Item”


FlowExecution
Significant architectural
differences
 One flow drives the entire conversation
 When user input is required, the flow
“pauses” and control returns to the client
 Clients “signal” events to tell the flow
what happened
 The flow responds to events to decide
what to do next
 What to do next is fully encapsulated
 Flows are modular “black boxes”
Flow Execution State Transition
D iagram

start Created Ending

end
Active Paused
subflow user input
spawned needed
user event
signaled

Resuming
Q uestion

Q: How do you program the Flow?


Q: How does it know what to do in
response to user events?

A: You create a Flow definition


Flow D efinition Structure
 A Flow definition serves as instructions to
a finite state machine
 It consists of a set of states that you
define
 Each state executes a polymorphic
behavior when entered
 View states solicit user input
 Action states execute commands
 Subflow states spawn child flows
 End states terminate flows

 Events you define drive state transitions


The “SellItem ” Flow D efinition

Enter Price Enter Shipping submit


start and Item Count Information

submit yes

Select Item Is Shipping


Category Process Sale
submit Required? no

View State
Action State
Show
Decision State Cost Overview
End State
Code Break!
 The “Sell Item” Flow Definition
 If viewing on-line, see presentation notes
 Demo of the Flow Execution
Advantages
 The logical flow is clearly defined, readable
 Navigation rules are encapsulated in one place
 No dependency on any request URLs
 Navigation is strictly enforced
 State management is automatic
 Flow lifecycle is fully observable
 Controller logic is clearly decoupled from
command logic
 The Flow is the controller, deciding what state to
enter next
 States execute arbitrary behavior when entered
 HTTP independent
 Flow definitions are extremely toolable
W alkthrough: Spring Air
 The best way to learn is by example
 The airline industry:
 Trip booking system
 This vertical slice must:
1. Obtain Trip Information
2. Suggest suitable itineraries
3. Assign seats
4. Collect passenger information
5. Book the trip!
Code Break!
 The “Booking Agent” business façade
 Subsystem boundary
 The model context
 The façade integration tests
Expressing the booking flow
Building the Booking Flow D efinition

 First select a FlowBuilder strategy


 XML, Java-based, Custom
 Perhaps with a supplemental drag ‘n drop
tool
 Then create the states of the flow
 Define the behavior to happen when each
state is entered
 Define the supported transitions from one
state to another
• Transitions map the paths through the Flow
Code Break!
 The Booking Flow Definition
 The Booking Flow Action
 The Action Unit Tests
 The Flow Execution Integration Tests
 The View Templates
 Application Deployment Configuration
The Booking Flow D efinition
<webflow id="booking“
start-state=“displayTripForm">
<! – state definitions go here 
</webflow>
Rendering the Trip Form

 Display the “trip form” so the user can tell the


flow where she wants to go

<view-state id="displayTripForm" view="tripForm">


<entry>
<action bean="bookingFlowActions" method="setupForm"/>
<action bean="formUtilityActions" method="setupDateChooser"/>
</entry>
<transition on="go" to="suggestItineraries">
<action bean="bookingFlowActions" method="bindAndValidate"/>
</transition>
</view-state>
Suggesting Trip Itineraries
 Suggest the best itineraries:

<action-state id="suggestItineraries">
<action bean=“bookingActions"/>
<transition on="success“ to="displaySuggestedItineraries"/>
</action-state>

 Action states invoke methods on Actions when


entered
 Can also directly invoke methods on POJOs
 Example:
 Entering “suggestItineraries” invokes the
“suggestItineraries” method on the action
identified by “bookingActions”
The Booking Action
Im plem entation
public class BookingAction extends FormAction {
private BookingAgent bookingAgent;

private BookingAction(BookingAgent agent) {


setFormObjectName("trip");
setFormObjectClass(Trip.class);
this.bookingAgent = agent;
}

public Event suggestItinenaries(RequestContext context) {


Trip trip = (Trip)context.getFlowScope().getAttribute("trip");
Collection<Itinerary> itineraries =
bookingAgent.suggestItineraries(trip);
context.getFlowScope().setAttribute("itineraries", itineraries);
return success();
}
// other action methods related to the booking process…
public Event book(RequestContext context) {

}
}
Selecting an Itinerary
 Display the itineraries and let the customer select one:

<view-state id="displaySuggestedItineraries"
view="suggestedItineraries">
<transition on="startOver" to="cancel"/>
<transition on="select" to=“recordSelectedItinerary"/>
</view-state>

<action-state id=“recordSelectedItinerary">
<action bean=“bookingActions"/>
<transition on="success" to="isPassengerInfoRequired"/>
</action-state>

 The flow pauses while the view is displayed for user “think time”
 The flow resumes in the same state on the next request (“post
back”) to decide where to go next
D eciding w here to go next
 Is passenger information required? If so, enter it. If
not, go straight to verification

<action-state id=“isPassengerInfoRequired”>
<transition on=“yes” to=“enterPassengerInformation”/>
<transition on=“no” to=“displayReservationVerification”/>
</action-state>

 A logical decision point: “routing state”


 A Decision State could have also been used
Entering Passenger Inform ation
 Spawn the “enter passenger information” process as
a subflow, passing it the passenger ID if they have
authenticated

<subflow-state id="enterPassengerInformation"
flow="passenger">
<attribute-mapper>
<input value="${requestScope.passenger.id}“ as=“id”/>
</attribute-mapper>
<transition on="finish" to="displayReservationVerification"/>
</subflow-state>

 Note: the parent flow suspends while the subflow


executes. When the subflow ends, the parent
responds to its result.
Finalizing the Reservation
 On verification, optionally choose seat assignments. Then book the
reservation!

<view-state id="displayReservationVerification"
view="reservationVerification">
<transition on="startOver" to="cancel"/>
<transition on="assignSeats" to="chooseSeatAssignments"/>
<transition on="book" to="book"/>
</view-state>

<action-state id="book">
<action bean=“bookingFlowActions"/>
<transition on="success" to="displayConfirmation"/>
</action-state>

<end-state id="displayConfirmation" view="reservationConfirmation"/>

 The end state terminates the flow when entered


 All flow resources are automatically cleaned up
D eploying the Flow
<bean name="/springair.htm“
class="org.springframework.web.flow.mvc.FlowController"/>

<bean id="booking“
class="org.springframework.web.flow.config.XmlFlowFactoryBean">
<property name="location“ value="classpath:/flows/booking.xml"/>
</bean>

 One Flow Controller can execute all flows for the


application at a single request URL
 The views parameterize the controller with flow
launching information
 Security would be at the flow level
Exam ple: view s launching flow s
 Using a form:

<form method=“post” action=“springair.htm”/>


<input type=“text” name=“src.airport”/>
<input type=“text” name=“dest.airport”/>

<input type=“hidden” name=“_flowId” value=“booking”/>
<input type=“submit” value=“Submit”/>
</form>

 Using an anchor:

<a href="<c:url
value="/springair.htm?_flowId=booking&src.airport=MLB&
dest.airport=ATL"/>">
Launch Booking Flow
</a>
Exam ples: view s participating in
flow s
 Using a form:

<form method=“post” action=“springair.htm”/>


<input type=“text” name=“firstName”/>
<input type=“text” name=“lastName”/>

<input type=“hidden” name=“_flowExecutionId”
value=“${flowExecutionId}”/>
<input type=“submit” name=“_eventId_submit”/>
</form>

 Using an anchor:

<a href="<c:url
value="/springair.htm?_flowExecutionId=${flowExecutionId}
& _eventId=submit&firstName=Keri&lastName=Donald/>“>Enter
Passenger Information</a>

 Each flow is assigned a unique identifier made available to the


views for storage
Issues and Solutions
 Browser navigation button use, flow storage and
restoration
 A stateful system brings challenges in a stateless
environment
 Continuations provide a solution
• Server-side session-based storage
• Client-side seralization using hidden form field
• Custom (database, file, etc.)
 Duplicate submits
 End States are one answer
 Redirects are another
<end-state id=“end”
view=“redirect:springair.html?flowId=anotherFlow”/>
 TransactionSynchronizer
• Token-based implementation relies on a secure token to be
present on the client and in flow scope
• Interface is pluggable
• Support for compensating transactions is of high interest to
us: ended flow “rollback”
Issues and Solutions
 Responding to the lifecycle of an executing flow
 Listeners may be attached to executing flows
 Callbacks are made on:
• Request submitted – good for pre-flow event processing
• Session starting – good for precondition checks
• Session started -- good for post condition checks
• Paused – good for custom view pre-render logic
• Resumed – good for pre-flow event processing
• State Entering – good for precondition checks
• State Entered – good for post condition checks
• Ended – good for custom cleanup logic
• Request processed – good for post processing logic
Issues and Solutions
 Annotating a Flow with metadata
 Any flow definition artifact can be annotated:
• Flow
• State
• Transition
• An action’s use in a action state

 Example:

<action-state=“book”>
<property name=“role” value=“passenger”
type=“grantedAuthority”/>
<action bean=“bookingAction”>
<property name=“caption” value=“Books the
reservation”/>
</action>
</action-state>
Issues and Solutions
 Integrating into other environments
 Create a specialized FlowController for that
environment
 For example:
• The FlowAction for Struts
• The FlowNavigationHandler for JSF
• The PortletFlowController for Portlets
 Spring Web Flow is not coupled with any other
web framework
 Not even Spring MVC or the Servlet API

 Proven in a Portlet environment

 Truly an embeddable component


D esign Tips
 What makes a good Web Flow?
 Accomplishes some business goal, e.g.
• Book a trip
• Pay your taxes
• Apply for a Loan
 Encapsulates that business goal as a reusable
module
• A “black box”
 Often has multiple paths to support different
scenarios
• Paths may vary based on contextual information
 Often spawns other Flows as sub flows
• Has a clear, observable lifecycle: Flow executions start,
events happens, they end
D esign Tips
 What doesn’t make a good Flow?
 Index pages
 Welcome Pages

 Menus

 Simple Form Submissions (Mailers, etc.)

 Sites with a lot of free navigation

 Web flows are best suited for enforcing


controlled navigation to support business
process workflows
 As a compliment to traditional controllers

 Don’t abuse them


Spring W eb Flow Road M ap
 JSF integration
 JMX-enabled flow management
 Ajax support
 Asynchronous View State Actions
 More configuration defaults
 Research in the area of compensating
transactions
 Research in the area of asynchronous,
parallel sub flows
Resources and U pcom ing Events
 www.springframework.org
 New CMS portal means we now bring you a lot
more content
 Web Flow Wiki provides a “Quick Start”
 Practical guide
 Articles
 Web Flow Ships with 7 sample applications
 Phone Book (Core sample)
 Sell Item (Wizard with Continuations)
 Birth Date (Struts integration)
 Item List (Transaction Synchronization)
 Number Guess (Example of conversation history)
 Flow Launcher (How to launch flows)
 File Upload (A flow to upload files)
Resources and U pcom ing Events
 Public Spring Training
 4-day “bootcamps” across North America, Europe
 www.springframework.com/training
 The Spring Experience
 International conference for agile Java developers
 http://www.thespringexperience.com
 December 7 – 10th, 2005, Sheraton Resort, Bal Harbour
Beach Florida
 40+ technical sessions across four tracks: Web, Enterprise,
Process, Beyond J2EE
 Featuring
• Rod Johnson (Spring Founder, i21 CEO)
• Juergen Hoeller (Spring Co-Founder, i21 CTO)
• Adrian Colyer (AspectJ Founder, i21 Chief Scientist)
• Rob Harrop (Author, Pro Spring)
• … and many more
 Super early bird registration period open now
Think Big: The Spring Experience
2005
Conclusion
 Spring is a complete, modular, pragmatic
full-stack application framework
 It adds serious value in:
 The middle tier

 The web tier

 Spring 1.3 will be a major upgrade to the


Spring web stack
 Spring will continue to innovate
 Spring will continue to simplify
Q uestions?

Вам также может понравиться