Spring WebFlow con JSP – Configuración
Voy a intentar explicar como funciona Spring WebFlow y para ello, como siempre, lo haré desarrollando un programa que podéis descargar de https://github.com/chuchip/webflowExample
El programa simulara que entras a la página de un banco donde puedes realizar una transferencia de tus cuentas personales a otra. Para ello, primero deberás identificarte y según el usuario con el que te identifiques tendrás acceso a unas cuentas que a su vez disponen de un saldo establecido. Para realizar todo esto utilizo H2 como base de datos y la autentificación se realiza con el paquete de seguridad de Spring, utilizando JDBC . Por hacer la página mas funcional utilizo Bootstrap y JQuery.
El programa esta realizado para que funcione bajo Tomcat, en el contexto: webflow. Por lo que deberemos ir a la dirección http://localhost:8080/webflow para probar nuestra aplicación:
En esta imagen se puede ver la definición del flujo de trabajo.
Spring WebFlow es un paquete con el cual podemos definir el flujo de nuestra aplicación. Es decir, definimos las acciones a realizar cuando se pulse un enlace, se cumpla cierta condición, etc. Estos flujos son definidos en ficheros XML, de tal manera que ahí es donde definimos que de la PAGINA_X, al pulsar el BOTON1, vaya a la PAGINA_XY, siempre y cuando la CONDICION_Z se cumpla. Esto nos permite separar la lógica del programa de las vistas (los ficheros JSP), ademas de ser más fácil el reutilizar código.
– Estructura
La estructura del programa es la que se ve en la imagen siguiente:
Dentro del directorio WEB-INF esta la carpeta flows, que a su vez tiene la carpeta traspaso y time donde definimos los dos flujos de trabajo que se usan en la aplicación. Observar que los ficheros xml con la definición del flujo de trabajo también se aloja en las mismas carpetas donde estan los JSP de su flujo. Es decir el flujo de trabajo “traspaso” se define en el fichero “traspaso.xml” y utiliza los ficheros: cuentaOrigen.jsp, importe.jsp, confirmar.jsp, _include.jsp y _navegador.jsp.
Dentro del directorio WEB-INF también se alojan las carpetas css y img donde se guardan respectivamente las plantillas css y las imágenes de la aplicación.** **
- Configurando la Base de Datos y Persistencia
Empezare mostrando las tablas usadas en la aplicación:
La tabla clientes, cuentas y cuentas_clientes son usadas por la lógica del programa, mientras que users y user_roles son usadas por el modulo de seguridad de spring.
La persistencia esta definida en la clase JpaConfig. Podéis ver una explicación de esta clase en la parte de la configuración de JPA de esta entrada: http://www.profesor-p.com/2018/09/03/aplicacion-en-spring-rest-y-angular-2-parte/#jpa
- Dependencias
Necesitaremos tener el paquete de JPA, JDBC, Hibernate, soporte de transaciones y por supuesto de H2.
- Configurando MVC y WEB-FLOW
En ella se configura la parte MVC de la aplicación. Así en la función addResourceHandlers especifico que los recursos de las peticiones a “webjars” deberán ser buscadas en el directorio /webjars y que los recursos de las peticiones a resources deberán ser buscadas en el directorio /WEB-INF/resources/. Es decir que cuando vayamos a http://localhost:8080/webflow/resources/XX deberá traer el fichero /WEB-INF/resources/XX
La función viewResolver establece que se usara la JSTL (que no es sino una extensión de JSP), especificando en que directorio y que extensiones debe resolver.
Las funciones FlowHandlerMapping y FlowHandlerAdapter especificaran los identificadores o registros de webflow y sus correspondiente ejecutores. Ahora explicare que es eso 😉
En esta clase configuramos webflow como tal, para ello lo primero es extender de la clase AbstractFlowConfiguration y definir las funciones que detallo a continuación:
En esta función se declaran los diferentes identificadores de los flujos a usar.Así tenemos que el identificador “traspaso” estará definido en el directorio “/WEB-INF/flows/traspaso/traspaso.xml
“. Esto lo que significa es que cuando vayamos a la dirección: http://localhost:8080/webflow/traspaso entraremos en el flujo que tenemos definido en el fichero indicado. A su vez, cuando vayamos a http://localhost:8080/webflow/traspaso_time entraremos al flujo declarado en “/WEB-INF/flows/traspaso/time/traspaso_time.xml
“.
En este caso yo defino individualmente los dos flujos, pero se pueden utilizar comodines para que Spring busque dentro de un directorio todos los ficheros que cumplan ciertos criterios. Así, la sentencia: .addFlowLocationPattern(<span class="hl-string">"/WEB-INF/flows/**/*-flow.xml"</span>)
especificaría que añadiera todos los flujos que encontrara en el directorio /WEB-INF/flows cuyo nombre terminara en “flow.xml”. Los identificadores en este caso serian los nombres de los ficheros sin la extensión xml. Es decir si tenemos el fichero: <span class="hl-string">/WEB-INF/flows/consulta-flow.xml</span>
el identificador seria “consulta-flow”
La siguiente función simplemente llama a la anterior para especificar los ejecutores de los registros anteriormente definidos.
Aclarar que el trabajo del F**lowExecutor** es crear y ejecutar los flujos de trabajo que anteriormente hayamos definido en los registros.
Las siguientes funciones unen las vistas (ficheros JSP) con el paquete webflow. Como se puede observar crea dos objetos en los cuales se definen las uniones entre el paquete MVC de Spring y el paquete WebFlow. Esto es así porque el paquete WebFlow también funciona con otros MVC como JavaServer Faces de JavaEE
- Dependencias
Ademas del paquete JSTL, también usamos el paquete spring-security-taglibs que es una extensión de JSTL que nos permite trabajar con el paquete de seguridad de Spring dentro de nuestros ficheros JSP. Por supuesto también debemos incluir el paquete spring-webflow
– Configurando la seguridad
No es mi intención el volver a explicar como funciona la seguridad en Spring, pues aunque en anteriores ejemplos (http://www.profesor-p.com/2018/10/17/seguridad-web-en-spring-boot/) los usuarios los guardaba en memoria en vez en una base de datos como en esta ocasión, realmente lo único que cambia es que se incluye la función: <strong>configure(AuthenticationManagerBuilder auth)</strong>
y se quita la función UserDetailsService de la clase SecurityWebConfig.
En esta función se configura la autentificación por jdbc de la clase AuthenticationManagerBuilder especificándole el DataSource a usar, así como las sentencias SQL a ejecutar para validar los usuarios y los roles de estos.
La clase configure(HttpSecurity http) configura la seguridad no teniendo nada en particular, solo resaltar que no deshabilito el modulo de seguridad CRSF por lo cual todas las peticiones POST deben incluir nuestro identificador CRSF. Lo veremos más tarde al explicar los ficheros JSP.
La clase SecurityWebApplicationInitializer que extiende de AbstractSecurityWebApplicationInitializer debe estar definida pues esta aplicación al no ser Spring Boot, sino Spring a secas la necesita para implementar la seguridad web. La configuración, simplemente es inexistente. Con que exista la clase es suficiente 😉
- Dependencias
Definimos los paquetes de seguridad de Spring, incluyendo el de seguridad web.
En la próxima entrada explicare el programa paso a paso 😉
¡¡ Nos vemos!!