Evitar doble-click en JSPs y Struts

0
25559

Control de Doble Click en JSP y Struts

Cuando realizamos una aplicación Web, hay un problema bastante común y se
produce cuando el usuario realiza una transacción:

  • Hace un doble click muy rápido sobre un botón invocando doblemente
    transacciones
  • Se pone nervioso y, antes de que termine, la vuelve a invocar.
  • Se produce un error y no está seguro de que las transacciones se hayan
    confirmado por lo que lo reintenta para ver que le dice el sistema..
  • Pulsa el botón volver, refrescar y avanzar con lo que reenvía una misma
    transacción dos veces.

Una de las soluciones, que habitualmente se utiliza, es escribir un pequeño
código JavaScript que nos permita evitar la situación (al menos parcialmente).

El primer problema de esta aproximación es conceptual: Jamás me debo fiar de
las validaciones realizadas en el cliente Web (aparte de la parcialidad de la
solución) porque:

  • Son fácilmente evitables.
  • JavaScript depende de la versión del navegador (y sistema operativo) que
    complica la mantenibilidad.
  • JavaScript puede desactivarse.
  • Podemos hacer un programas que automatice una petición HTTP sin que exista
    un navegador (y empezad a pensar en WebServices)

Las validaciones importantes hay que controlarlas siempre en el servidor
(aunque las complementemos en el cliente para evitar flujos innecesarios de
información).

Tenemos que entender los posibles estados que podemos tener el problema:

  1. Un usuario llega a un punto que donde se autoriza una nueva transacción
    (se activa un ticket o token)
  2. El usuario ejecuta una vez esa transacción y se deshabilita el token
  3. El usuario para poder ejecutar esa misma transacción de nuevo tiene que
    llegar a un punto que le vuelva a habilitar el token

El párrafo anterior está escrito en un lenguaje poco técnico lo
que provoca ambigüedades . Podríamos tratar de utilizar UML para concretar un
poquito más los posibles estados y tratar de plasmar en el futuro las posibles
variaciones.

Este problema lo podríamos tener tanto en una aplicación con interfaz tipo
Windows o en una aplicación Web ….. Lo lógico sería tratar de construir una
librería que pudiera se invocada por distintos tipos de aplicaciones.

Nosotros no vamos a ir tan allá pero trataremos de dar el primer paso en la
solución creando unas librerías de etiquetas básicas para resolverlo en
aplicaciones Web/JSP.

Construiremos un pequeño ejemplo que veremos elemento a elemento.

El formulario

Partimos de un formulario donde mandaremos al servidor un campo oculto. En
este campo se almacena un valor que solo es utilizable una vez. El encargado de
generar y validar este parámetro es siempre el servidor y lo hacemos a través de
una etiqueta. Pasamos como parámetro el nombre de la transacción (ejemplo)
para poder tener tantos tokens activos como deseemos.

<controltokens:generaToken nombreTransaccion=»ejemplo«/>

Podemos ver el aspecto de la página

Y el código que llegaría a nuestro navegador. Hemos elegido como
token la fecha actual pero podría ser cualquier cosa

La rutina transaccional

Cuando ejecutemos la transacción debemos verificar que el toquen es válido.
Usamos otro JSP.

<controltokens:compruebaToken nombreTransaccion=»ejemplo«/>

Si no es así, generamos una excepción y redirigimos a una página de error

 errorPage=»/pages/transaccionDuplicada.jsp«

Si la ejecutamos una vez

Si ejecutamos la segunda vez (con refrescar, volver y enviar,
volver-refrescar y enviar).

Limpiar el token

En el caso de querer volver a ejecutar la transacción deberíamos
pasar por una página que rehabilitase el token.

<controltokens:anulaToken nombreTransaccion=»ejemplo«/>

Librería de TAGS

Ahora solo tenemos que revisar el tutorial donde
os mostrábamos como crear
paso a paso una etiqueta
y analizar el código particular.

El tag de generación de token

El tag de Verificación/desactivación

El tag de reactivación

No olvidar modificar el fichero web.xml para poder utilizar las tags
en nuestras páginas JSP

Como habréis podido observar el efecto es el deseado aunque todavía quedarían
por dar muchos pasos:

  • Deberíamos construir un juego de pruebas detallado que nos garantizase su
    correcto comportamiento.
  • Como segundo paso deberíamos sacar del código de las TAGs a librerías más
    genéricas para utilizarlas en aplicaciones tipo MVC y otro tipo de interfaces.
  • Como tercer paso, deberíamos ligar estas capacidades dentro de nuestro
    FrameWorks para que incluso se generase automáticamente el código redundante
    en el cliente
  • Y aún podríamos hacer más cosas….

Control de transacciones y Struts

Mucha gente utiliza Struts pensando que el control de transacciones y doble
clicks ya esta solucionado…. pero no es así de automático.

En la acción que deseamos que active el control transaccional (previo al
formulario) debemos llamar a la función:

saveToken(httpServletRequest);

Los formularios tenemos que montarlos con la etiqueta de Struts html

Podemos ver que pasa algo similar a lo que hicimos con nuestras tags

Posteriormente en la acción que ejecuta la transacción podemos verificar el
token e invalidarlo con:

 if( this.isTokenValid(httpServletRequest)==true)

Y luego limpiarlo con

 this.resetToken(httpServletRequest);

Conclusiones

El desarrollo de aplicaciones Web es un arte bastante compleja aunque
aparentemente pudiera parecer lo contrario  Uno de los problemas es que la
misma cosa se puede hacer de muchos modos y es fácil que elijamos uno poco
afortunado.

Este ejemplo no soluciona todos los problemas pero sienta unas bases para el
estudio y solución del mismo..

Si estudiáis metodologías tipo Programación Extrema, observareis que uno de
los principios a tener en cuenta es realizar diseños sencillos. Esto significa
(y es una posible interpretación personal) que no debemos diseñar una solución
pensando en los problemas que tendremos dentro de dos años sino los que
tendremos dentro de dos meses… Dentro de dos años ya veremos….

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad