Spring Web Flow
-
Upload
colin2012 -
Category
Technology
-
view
3.500 -
download
0
Transcript of Spring Web Flow
Spring Web Flow
Colin Fairless
Agenda
• Motivación
• Solución Spring Web Flow
• Implementando procesos
• Reuso de procesos
• Pruebas
• Demo
Motivación
• La mayoría de aplicaciones web tienen estado• Cualquier aplicación donde el usuario ingresa
toda la data requerida por una única transacción de negocio mediante varias páginas– Checkout de carrito de compras– Reservando un vuelo online
• Data parcial de las páginas anteriores está guardada en sesión HTTP o en base de datos– Manejado explícitamente por la aplicación.
Desafíos de Web Apps con estado
• HTTP es un protocolo sin estado– Cada request es un evento aislado
• Frameworks tradicionales son request driven– Cada página hace submit a un controller
distinto– Cada controller es responsable sólo por un
único paso en el proceso completo
Desafíos de Web Apps con estado
• Muchos caminos de navegación pueden ser dificiles de manejar– Sin un lugar central para manejar navegación
• Los scopes de Request y Session a veces no son suficientes– Redirect del lado del cliente limpia el scope
del Request– Problema de double post y botón regresar
• Difícil probar
Aplicaciones Web tradicionales con estado
Agenda
• Motivación
• Solución Spring Web Flow
• Implementando procesos
• Reuso de procesos
• Pruebas
• Demo
Process Driven Application
• Define toda la navegación en un lugar central
• Maneja la interacción completa como una entidad única
• Deja al framework decidir qué hacer y adónde ir dependiendo de los eventos invocados por el usuario
Process Driven Application
Diagrama de Flujo
Modelando Proceso
• Flow execution = nuevas conversaciones del usuario con el servidor• Pasos en el flujo se llaman estado• Cada estado tiene una o más transiciones que son usadas para
mover a otro estado• Una transición es disparada por un evento
Estados
• View State– Hacer una pausa en una ejecución y hacer un render
de la vista para obtener input del usuario
• Action State– Ejecutar código Java– Se puede hacer transición a estados diferentes
dependiendo del resultado
• Decision State– Ramas de la lógica
Estados
• Subflow State– Transferir ejecución a un flujo diferente– Ejecución volverá a este estado cuando el
subflujo termine
• End State– Estado final del flujo– Puede o no definir una vista para presentar
Variables
• Web Flow te permite definir variables como parte del proceso del modelo
• Se puede guardar variables en uno de los scopes diferentes– Conversation, Flow, Flash, View, Request
Conversational y Flow Scopes
• Conversation scope disponible a todos los flujos
• Flow scope limitado solamente a un flujo individual
Flash Scope
• Limpiado una vez que se presentó la vista
• Útil para guardar resultados temporales de los Action States
• Sobrevive los redirects del cliente
View Scope
• Creado una vez que entra al View State
• Destruido cuando sale de la vista
• Útil en páginas que submiten muchos requests AJAX
Request y Session Scopes
• El Request Scope tradicional todavía está disponible– El mismo lapso de vida que siempre– No sobrevive redirects del cliente
• Session Scope no es fácil de acceder– Es más grande que el Conversation Scope– No tiene sentido desde WebFlow– Interactúa con sesión via atributos de input y
output del flujo
Agenda
• Motivación
• Solución Spring Web Flow
• Implementando procesos
• Reuso de procesos
• Pruebas
• Demo
Modelando el proceso
• Domain Specific Language (DSL) disponible de la caja– XML
• Se puede definir un flujo programáticamente
• Implementa FlowAssembler y FlowBuilder para crear tu própio flow definition language
– Poco impacto cuando es introducido a proyectos existentes
– Puntos de entrada a otros frameworks son consistentes
• Spring Webflow es autocontenido
Integración
Definición del Flujo
<flow xmlns=“…”>
<input name="cart“
required="true“
type=“com.mycomp…" />
<decision-state id=“hasItems">
<if test="cart.empty" then="goShopping“
else="enterAddresses"/>
</decision-state>
Definición del Flujo
<view-state id="enterAddresses“><transition
on="next“to="shipMethod" />
</view-state>
<view-state id="shipMethod"><transition
on="back“
to="enterAddresses" /><transition
on="next“to="calculateTax" />
</view-state>
Definición del Flujo
<action-state id="calculateTax">
<evaluate expression=“basketService.calcTax(cart)" />
<transition to="ccInfo" />
</action-state>
<view-state id="ccInfo">…
</view-state>
Evaluate
• El punto de conección primario entre WebFlow y servicios de backend
• Expresión dentro del evaluate tag es Unified EL– El mismo lenguaje de expresión usado en
JSP 2.1– Se puede referenciar a los spring beans
directamente por nombre– Acceso a variables del scope
• flashScope.foo
Evaluate
• Usar en Action States• Usar en View States
– on-entry– on-render– on-exit
• Usar en Flow– on-start– on-end
• Usar en Transicion
Definición del Flujo
<action-state id="validateCC">
<evaluate
expression=“basketService.validateCC(cart)" />
<transition on=“yes" to="confirm" />
<transition on=“no" to="ccInfo" />
</action-state>
Definición del Flujo
<action-state id="processOrder">
<evaluate expression=“…”/>
<transition to="thankYou" />
</action-state>
<end-state id="thankYou“ view=“thankYou”>
<output name=“confirmationNumber”
value=“cart.confirmationNumber” />
</end-state>
<end-state id="goShopping" view="externalRedirect:servletRelative:/home"/>
Codificando la Vista
• Forms de HTML estándar
• Se puede usar form tags de Spring MVC
• Variables de todos los scopes disponibles en expresiones EL como request scoped variables
• Siempre envia POST al flow controller– EL Variable: ${flowExecutionUrl}
Invocando Evento
<input type=“submit” name=“_eventId_back”
value=“Back” />
<input type=“submit” name=“_eventId_next”
value=“Next” />
<a href=“${flowExecutionUrl}&_eventId=next”>
Next</a>
• Enlace
• Botón nombrado
Agenda
• Motivación
• Solución Spring Webflow
• Implementando procesos
• Reuso de procesos
• Pruebas
• Demo
Subflujos
• Igual a un flujo normal
• Llama a un flujo desde otro flujo
• Tiene su propio namespace de variables– Flow scope no compartido entre flujos– Conversational scope es compartido entre
flujos
• Análogo a una llamada al método en código Java
Diagrama de Flujo
Diagrama de Flujo
Subflujo
Definición de Subflujo
<view-state id="enterAddresses">
<transition on="next" to="shipMethod" />
<transition on="addrBook" to="addrBook" />
</view-state>
<subflow-state id="addrBook“
subflow="addressBookFlow">
<attribute name="user" value="cart.user" />
<transition to=“enterAddresses” />
</subflow-state>
Aplicando seguridad a Web Flow
<view-state id="enterAddresses"><transition on="next" to="shipMethod" /><transition on="addrBook" to="addrBook" />
</view-state>
<subflow-state id="addrBook“subflow="addressBookFlow">
<secured attributes=“ROLE_AUTHENTICATED” /><attribute name="user" value="cart.user" /><transition to=“enterAddresses” />
</subflow-state>
Aplicando seguridad a Web Flow
• Integra con Spring Security
• Se puede aplicar el tag <secured> a– States– Transitions– Flows
• AccessDeniedException lanzado– Manejado por Spring Security según su
própia configuración
Agenda
• Motivación
• Spring Webflow
• Implementando procesos
• Reuso de procesos
• Pruebas
• Demo
Probando WebFlow
• Probando un proceso web de múltiples páginas puede ser muy difícil– Normalmente involucra la preparación de un
servidor de pruebas y la ejecución de la aplicación
– Difícil aislar la definición del flujo desde la ejecución
– Difícil probar los pasos en el medio sin ejecutar todos los pasos previos
Probando WebFlow
• WebFlow viene con la clase AbstractXmlFlowExecutionTest– Prueba de JUnit– Todas las pruebas corren dentro de un contenedor
Spring, con todos los objetos conectados
• Al mínimo, especificar la ubicación de tu definición XML del flujo
• Se dan puntos de extensión útiles– Registrar stubs y mocks con el contenedor Spring– Especificar ubicación de la definición del flujo padre si
es necesario
AbstractXmlFlowExecutionTest
• Maneja ejecución del flujo– startFlow(), setCurrentState(), resumeFlow()
• Afirmaciones– assertCurrentStateEquals()– assertFlowExecutionEnded()– más
• Acceso a Scoped Variables– Get y set
MockExternalContext
• Usar esta clase para poblar cualquier estado externo esperado para el pedazo de flujo en prueba– setCurrentUser()– setEventId()– getRequestParameterMap().put(“name”,
“value”)
Prueba de ejemplo: Haciendo transiciones
public void testSomething() throws Exception {
setCurrentState(“enterAddresses”);
MockExternalContext context =
new MockExternalContext(); context.setEventId(“next”);
resumeFlow(context);
assertCurrentStateEquals(“shipMethod”);
}
Agenda
• Motivación
• Solución Spring Webflow
• Implementando procesos
• Reuso de procesos
• Pruebas
• Demo
Demo
Resumen
• Desarrollo de aplicaciones web con estado– Abordaje Process Driven es muy diferente al
abordaje Request Driven usado en aplicaciones MVC tradicionales
• Modelar proceso de negocio como unidad única– WebFlow usa un Domain Specific Language
(DSL) análogo a un diagrama de flujo para modelar el proceso en un archivo único
Resumen
• Procesos son reutilizables por áreas distintas de la aplicación– Flujos pueden ser invocados desde otros
fllujos. Flujos pueden recibir parámetros de input y devolver valores de output.
• Fácil probar– AbstractXmlFlowExecutionTests y
MockExecutionContext permiten probar definiciones de flujos en aislamiento de la lógica de la aplicación