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.

Flujo de trabajo 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!!