42
En el presente capítulo veremos el Struts Validator, un componente con funcionalidad para validar automáticamente nuestros formularios. Manejaremos sus validaciones básicas y aprenderemos a crear nuevas. Struts Validator Validar los formularios................. 2 Definir un validador ...................... 5 Validaciones estándar ................... 7 Validación en el cliente ............... 18 Un validador propio .................... 23 Validaciones multipágina ............ 28 Mostrar errores con estilo........... 33 El ejemplo completo ................... 35 Resumen ..................................... 41 Actividades ................................. 42

C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

Embed Size (px)

Citation preview

Page 1: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

En el presente capítulo veremos el Struts Validator, un componente

con funcionalidad para validar automáticamente nuestros formularios.

Manejaremos sus validaciones básicas y aprenderemos a crear nuevas.

Struts Validator

▼Validar los formularios .................2

Defi nir un validador ......................5Validaciones estándar ...................7Validación en el cliente ...............18Un validador propio ....................23Validaciones multipágina ............28

Mostrar errores con estilo...........33El ejemplo completo ...................35

▼Resumen .....................................41

▼Actividades .................................42

C#_Struts_Validator.indd 1C#_Struts_Validator.indd 1 08/09/2014 10:4308/09/2014 10:43

Page 2: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR2

www.redusers.com

Validar los formulariosEn el Capítulo 5 vimos cómo programar nuestros objetos ActionForm

para que se validen los datos ingresados por el usuario. Este enfoque

es útil para validaciones complejas; sin embargo, la mayoría de las ve-

ces las validaciones que necesitaremos realizar en los formularios son

muy simples: que un campo no quede vacío, que un campo sea numé-

rico, que un campo contenga una fecha válida, etcétera. En estos casos,

implementar el método Validate para repetir las mismas validaciones

básicas es un proceso que podría simplifi carse. Además, se suma el

hecho de que probablemente queramos usar forms como DynaActionForm

o LazyValidatorForm para evitar crear una clase por cada formulario, y, en

esos casos, no tendremos dónde implementar el método Validate. Para

todos estos casos, Struts Validator es la mejor herramienta a utilizar.

Struts Validator es un componente muy poderoso y simple de usar

para casos sencillos. No obstante esto, provee funcionalidades como

para poder defi nir cualquier tipo de validador propio.

Lo que primero debemos hacer para empezar a usar el validador es

declararlo en el archivo struts-confi g.xml.

El validador es un plugin, esto es, un componente que Struts carga

al iniciarse y destruye al fi nalizar su ejecución.

Los elementos plugin son el último tipo de elemento que defi nimos

en el archivo de confi guración. Veamos cómo defi nir el validador:

El componente de validación de Struts no es más que una interfaz para el proyecto

Commons Validator, un proyecto de Apache. Este proyecto provee todo tipo de validaciones

y se lo puede usar tanto en aplicaciones web como en cualquier otro tipo de aplicación que

necesite de validaciones. Su sitio web: http://jakarta.apache.org/commons/validator.

COMMONS VALIDATOR

C#_Struts_Validator.indd 2C#_Struts_Validator.indd 2 08/09/2014 10:4308/09/2014 10:43

Page 3: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 3

www.redusers.com

El elemento plugin toma un atributo de nombre className que espe-

cifi ca la clase (que ha de implementar la interfaz org.apache.struts.action.

PlugIn) a instanciar. Dentro del cuerpo del elemento, podemos defi nir

un conjunto de elementos set-property, que establecen valores a propie-

dades de la clase al instanciarse.

En el caso de la clase ValidatorPlugin, las propiedades a las que pode-

mos establecer su valor son:

• pathnames: una lista de nombres de archivo, separados por coma,

que contienen las descripciones de las validaciones a realizar.

Es muy importante no olvidar agregar los archivos XML que vayamos

creando a esta lista; si no, por más que defi namos correctamente el

resto de las confi guraciones, la validación no se realizará.

<plug-in className=”org.apache.struts.validator.ValidatorPlugIn”>

<set-property property=”pathnames” value=”/

WEB-INF/validations/validator-rules.xml” />

<set-property property=”stopOnFirstError” value=”true” />

</plug-in>

En los ejemplos del capítulo omitiremos, por claridad y legibilidad, el uso de acentos

en el archivo de recursos. Recordemos que podemos escribir palabras acentuadas,

pero estas serán enviadas al navegador y puede que no se vean correctamente.

Para usar palabras acentuadas, en el archivo de recursos debemos hacerlo usando la

entidad HTML correspondiente (por ejemplo, &oacute; para ó).

ACENTOS EN ARCHIVOS DE RECURSOS

C#_Struts_Validator.indd 3C#_Struts_Validator.indd 3 08/09/2014 10:4308/09/2014 10:43

Page 4: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR4

www.redusers.com

• stopOnFirstError: si es true, se detendrá la validación de JavaScript al

primer error encontrado y se mostrará dicho error. Caso contrario,

se validarán todos los campos y se mostrarán todos los errores juntos.

Como vemos, en principio estamos defi niendo solamente un archivo

de confi guración de validación.

El archivo validator-rules.xml (ubicado en la carpeta raíz de la distri-

bución Library de Struts) contiene las descripciones de las validaciones

básicas que provee Struts en base al proyecto Commons Validator.

Estas validaciones estándar usan ciertas claves del archivo de recursos

para mostrar los errores. Por eso, para su correcto uso, es necesario

que agreguemos al archivo de recursos las siguientes claves (los valo-

res podemos cambiarlos a nuestro gusto o idioma):

errors.required={0} es requerido.

errors.minlength={0} no puede ser menor de {1} caracteres.

errors.maxlength={0} no puede ser mayor de {1} caracteres.

errors.invalid={0} es invalido.

errors.byte={0} debe ser un byte.

errors.short={0} debe ser un short.

errors.integer={0} debe ser un integer.

errors.long={0} debe ser un long.

errors.fl oat={0} debe ser un fl oat.

errors.double={0} debe ser un double.

errors.date={0} no es una fecha.

errors.range={0} no está en el rango {1} - {2}.

C#_Struts_Validator.indd 4C#_Struts_Validator.indd 4 08/09/2014 10:4308/09/2014 10:43

Page 5: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 5

www.redusers.com

En cuanto conozcamos cada tipo de validación, veremos cómo se

utilizan estos mensajes.

Defi nir un validadorPara defi nir validaciones sobre un formulario, debemos proveerle al vali-

dador un archivo XML. Técnicamente, podríamos agregar al archivo validator-

rules.xml los elementos XML para las validaciones, pero es una práctica no

recomendada. Una buena práctica es crear un archivo XML para cada formula-

rio que deseemos validar. Veamos en qué consiste este archivo:

errors.creditcard={0} es una tarjeta de credito invalida.

errors.email={0} no es una direccion de correo electronico valida.

errors.url={0} no es una direccion web valida.

<!DOCTYPE form-validation PUBLIC

“-//Apache Software Foundation//DTD Commons Validator

Rules Confi guration 1.1.3//EN”

“http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd”>

<!-- Elemento raíz -->

<form-validation>

<!-- Conjunto de formularios -->

<formset>

<!-- Agregamos nuestro formulario al conjunto -->

<form name=”proyectoForm”>

C#_Struts_Validator.indd 5C#_Struts_Validator.indd 5 08/09/2014 10:4308/09/2014 10:43

Page 6: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR6

www.redusers.com

El validador internamente tiene un conjunto de objetos llamado

formset. Cada elemento form, dentro de este elemento, agrega un

formulario al conjunto de formularios que tendrán validación.

Veamos elemento por elemento el archivo:

Mediante este elemento, declaramos que estamos defi niendo la vali-

dación para el formulario de nombre proyectoForm. Este form debe exis-

tir con este nombre en el struts-confi g.xml.

<form name=”proyectoForm”>

<!-- Primer campo a validar -->

<fi eld property=”nombre” depends=”required”>

<arg position=”0” key=”proyecto.nombre” />

</fi eld>

<!-- Segundo campo a validar -->

<fi eld property=”fecha” depends=”date”>

<arg position=”0” key=”proyecto.fecha” />

<var>

<var-name>datePattern</var-name>

<var-value>MM/dd/yy</var-value>

</var>

</fi eld>

</form>

</formset>

</form-validation>

C#_Struts_Validator.indd 6C#_Struts_Validator.indd 6 08/09/2014 10:4308/09/2014 10:43

Page 7: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 7

www.redusers.com

En un formulario, podemos validar uno o más campos. Cada elemen-

to fi eld defi ne un campo y las validaciones que han de realizarse sobre

él cuando el formulario sea enviado. El campo que validamos lo defi ni-

mos con el atributo property. Las validaciones que se efectuarán sobre

el campo las defi nimos mediante el atributo depends. Si queremos reali-

zar más de una validación, las escribimos separadas por comas.

Un campo debe pasar todas las validaciones para que sea válido. En

el cuerpo del tag fi eld insertaremos elementos y propiedades diversas,

dependiendo del tipo de validación que estemos efectuando.

Validaciones estándarVeamos cuáles son las validaciones que Struts provee, su uso y cómo

confi gurarlas. En todos los casos, los elementos arg dentro del elemento

fi eld defi nen la clave del archivo de recursos con la etiqueta del campo

a ser usada por el mensaje de error. Por ejemplo, para el validador

required, el mensaje de error es:

<fi eld property=”nombre” depends=”required”> <arg position=”0” key=”proyecto.nombre” /></fi eld>

Si bien los archivos de validación no tienen restricciones sobre su ubicación, es una

buena práctica agruparlos en una carpeta (o más, si se desea) dentro de la carpeta

WEB-INF. En una aplicación de tamaño mediano a grande, este tipo de archivos crece

considerablemente y es conveniente, entonces, tenerlos guardados en una subcarpeta.

UBICACIÓN DE ARCHIVOS DE VALIDACIÓN

C#_Struts_Validator.indd 7C#_Struts_Validator.indd 7 08/09/2014 10:4308/09/2014 10:43

Page 8: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR8

www.redusers.com

Si nuestro arg de posición 0 es, como en el ejemplo, proyecto.nombre,

y su valor en castellano es nombre, entonces, al producirse un error y

mostrarlo en la página, veremos:

nombre es requerido

requiredValida que el campo contenga un valor. Ejemplo de uso:

minlength, maxlengthVerifi can que el campo tenga un número mínimo o máximo de caracte-

res, respectivamente. Estos elementos toman una variable especifi cando el

valor del mínimo o máximo: minlength y maxlength. Ejemplo de uso:

errors.required={0} es requerido.

<fi eld property=”nombre” depends=”required”> <arg position=”0” key=”proyecto.nombre” /></fi eld>

<fi eld property=”nombre” depends=”minlength”> <arg position=”0” key=”form.nombre” /> <arg position=”1” key=”5” /> <var> <var-name>minlength</var-name> <var-value>5</var-value> </var></fi eld>

C#_Struts_Validator.indd 8C#_Struts_Validator.indd 8 08/09/2014 10:4308/09/2014 10:43

Page 9: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 9

www.redusers.com

Este es un ejemplo para validar un campo

con un número mínimo de caracteres. Para

validar por el máximo, es igual: se reempla-

za por maxlength, en vez de minlength.

Viendo este ejemplo, notamos dos incon-

venientes. El primero es que tenemos que

repetir el valor mínimo (o máximo) tanto en

la variable como en el argumento del mensa-

je. El segundo, y más importante, es que el

segundo atributo de arg es key, o sea, la cla-

ve de una entrada en el archivo de recursos.

Esto quiere decir que... ¡tendríamos que generar una entrada en el archi-

vo de recursos por cada número que usemos en los validadores!

Afortunadamente, podemos resolver estos dos inconvenientes. Para el

primer problema, simplemente podemos establecer una referencia al valor

de la variable que defi nimos en el elemento var. Para el segundo problema,

existe el atributo resource, dentro de los elementos arg, que especifi ca si el

valor es una clave del archivo de recursos o si es un valor literal. Veamos

entonces el mismo ejemplo anterior pero con estas salvedades:

El atributo key del segundo elemento arg hace referencia al valor de

la variable minlength, y, a su vez, defi ne que dicho valor no es una clave

del archivo de recursos sino el valor en sí.

<fi eld property=”nombre” depends=”minlength”> <arg position=”0” key=”form.nombre” /> <arg position=”1” name=”minlength” key=”${var:minlength}” resource=”false” /> <var> <var-name>minlength</var-name> <var-value>5</var-value> </var></fi eld>

PARA DEFINIR

VALIDACIONES

PROVEEMOS UN

ARCHIVO .XML PARA

EL VALIDADOR

C#_Struts_Validator.indd 9C#_Struts_Validator.indd 9 08/09/2014 10:4308/09/2014 10:43

Page 10: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR10

www.redusers.com

maskValida el campo según una expresión regular. Si el valor del campo

se ajusta a la expresión regular, entonces se lo considera válido. Este

validador es muy útil para comparar y admitir formatos específi cos en

los campos. Veamos un ejemplo: supongamos que un campo del formu-

lario pide al usuario el código postal de su residencia. Supongamos,

también, que todo código postal válido consta de 3 letras y 4 dígitos.

Entonces, defi nimos así el siguiente validador:

Este validará la propiedad cp del formulario. En la variable mask de-

fi nimos la expresión regular. Esta debe empezar con el signo ^ y debe

terminar con el signo $. El validador mask es un genérico y, por consi-

guiente, no tiene un mensaje de error por defecto. En el ejemplo, ve-

<fi eld property=”cp” depends=”mask”> <msg name=”mask” key=”form.cp.msg”/> <arg key=”form.cp” position=”0” /> <var> <var-name>mask</var-name> <var-value>^[a-zA-Z]{3}[0-9]{4}$</var-value> </var></fi eld>

El validador mask no usa las expresiones regulares de Java sino las que provee el

proyecto Jakarta ORO. Estas expresiones son ligeramente distintas de las de Java: son

expresiones regulares del estilo Perl5. Para un detalle de cómo hacer expresiones

regulares en ese estilo, podemos ingresar a http://jakarta.apache.org/oro.

EXPRESIONES REGULARES EN STRUTS

C#_Struts_Validator.indd 10C#_Struts_Validator.indd 10 08/09/2014 10:4308/09/2014 10:43

Page 11: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 11

www.redusers.com

mos el elemento msg. Dicho atributo especifi ca la clave, para el valida-

dor mask, del mensaje de error. Si el mensaje de error tuviera variables,

además podemos especifi car un elemento arg.

Las entradas para el archivo de recursos correspondientes son:

byte, short, integer, long, fl oat, doubleEstos validadores verifi can que el valor del campo pueda ser conver-

tido al tipo dado. En todos los casos, no se necesita otra variable más

que el argumento para el mensaje de error. Veamos dos ejemplos:

dateEste validador verifi ca que el valor del campo represente una fecha según

el patrón de conversión que se haya otorgado. Las posibles variables son

datePattern y datePatternStrict. La diferencia entre estos dos es que date-

PatternStrict, como su nombre lo indica, es estricto en cuanto a la canti-

dad de caracteres. Por ejemplo, con un patrón dd/MM/yyyy, la fecha

4/6/1979 fallará si el patrón es declarado como datePatternStrict. Para

este caso, la fecha correcta sería 04/06/1979.

form.cp=Codigo postalform.cp.msg={0} debe ser de la forma ABC1234

<fi eld property=”edad” depends=”integer”> <arg key=”form.edad” position=”0” /></fi eld>

<fi eld property=”sueldo” depends=”double”> <arg key=”form.sueldo” position=”0” /></fi eld>

C#_Struts_Validator.indd 11C#_Struts_Validator.indd 11 08/09/2014 10:4308/09/2014 10:43

Page 12: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR12

www.redusers.com

intRange, fl oatRange, doubleRangeCon estos validadores podemos verifi car que el valor de un campo se

encuentre dentro de cierto rango. Por lo general, se utilizan en conjunto

con el validador de tipo acorde. Por ejemplo, intRange lo usaremos en con-

junto con el validador integer. Las variables que usan son min y max, que

especifi can, como es de esperarse, la cota inferior y superior. Al igual que

con minlength y maxlength, los argumentos para el mensaje de error los es-

pecifi caremos como una referencia a la variable. Veamos el ejemplo:

<fi eld property=”fecha_nacimiento” depends=”date”> <arg key=”form.fecha_nacimiento” position=”0” /> <var> <var-name>datePattern</var-name> <var-value>dd/MM/yyyy</var-value> </var></fi eld>

<fi eld property=”litros” depends=”integer, intRange”> <arg key=”form.litros” position=”0” /> <arg name=”intRange” key=”${var:min}” resource=”false” position=”1” /> <arg name=”intRange” key=”${var:max}” resource=”false” position=”2” /> <var> <var-name>min</var-name> <var-value>4</var-value> </var> <var> <var-name>max</var-name> <var-value>24</var-value> </var></fi eld>

C#_Struts_Validator.indd 12C#_Struts_Validator.indd 12 08/09/2014 10:4308/09/2014 10:43

Page 13: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 13

www.redusers.com

creditCardCorrobora que el campo sea un número de tarjeta de crédito válido.

emailValida que el campo sea una dirección de correo electrónico válida.

urlValida que el campo sea una dirección web válida. Este validador

posee 4 variables, todas opcionales:

• allowallschemes: si esta variable es true, cualquier esquema será válido;

caso contrario, solo los especifi cados por la variable schemes.

• allow2slashes: si el valor es true, se aceptarán dos barras / consecutivas.

<fi eld property=”tarjeta” depends=”creditCard”> <arg key=”form.tarjeta” position=”0” /></fi eld>

<fi eld property=”correo” depends=”email”> <arg key=”form.correo” position=”0” /></fi eld>

Existen muchas opciones para determinar si una dirección web es válida o no.

El documento RFC 2396, disponible en la dirección www.ietf.org/rfc/rfc2396.txt,

especifi ca de manera precisa el estándar existente de las direcciones web.

DIRECCIONES WEB

C#_Struts_Validator.indd 13C#_Struts_Validator.indd 13 08/09/2014 10:4308/09/2014 10:43

Page 14: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR14

www.redusers.com

• nofragments: si es true, no se aceptarán direcciones web que contengan

fragmentos.

• schemes: especifi ca los esquemas válidos a ser considerados: por

defecto, HTTP, HTTPS y FTP.

Notemos que si especifi camos allowallschemes con valor true, entonces el

valor de schemes será omitido.

Ejemplos:

Esta confi guración aceptará http://onweb.tectimes.com y https://

java.sun.com, pero no http://www.jengibre.com.ar#anchor (tiene frag-

mento), ftp://sitio.ftp.com (esquema inválido) y http://www.jengibre.

com.ar//index.html (dos barras consecutivas).

validwhenCuando necesitamos validar un campo pero en función de otro campo,

ninguna de las validaciones vistas hasta ahora nos sirve, ni siquiera la

validación realizada por el método validate en un ActionForm.

Este validador sirve exactamente para estos casos. El ejemplo típico

es cuando pedimos a un usuario que ingrese su clave en un campo y la

<fi eld property=”url” depends=”url”> <arg key=”form.url” position=”0” /> <var> <var-name>nofragments</var-name> <var-value>true</var-value> </var> <var> <var-name>schemes</var-name> <var-value>http,https</var-value> </var></fi eld>

C#_Struts_Validator.indd 14C#_Struts_Validator.indd 14 08/09/2014 10:4308/09/2014 10:43

Page 15: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 15

www.redusers.com

reingrese en otro campo, como confi rmación. Ninguno de estos campos

es válido o inválido por sí solo, sino que su validez está dada por am-

bos valores. El validador toma solamente una variable de nombre test,

que debe contener una expresión booleana. Si la evaluación de la expre-

sión es verdadera, la validación es exitosa.

La expresión booleana tiene reglas sintácticas que debemos respetar:

• Toda comparación debe estar encerrada entre paréntesis.

• Los conectores and y or solo conectan dos elementos.

Los valores posibles son:

• Nombre de un campo del formulario.

• Cadenas de texto encerradas por comillas simples o dobles.

• El literal null.

• El literal *this*, que representa el valor del campo actual.

Si los valores a ser comparados pueden ser convertidos a enteros, se

realiza una comparación numérica; en otro caso, una comparación textual.

Supongamos que tenemos dos campos. Estos campos son válidos si

los dos contienen un valor o si ninguno contiene un valor. Esto sería

una extensión al validador required. Dados los campos campo1 y campo2,

la expresión que realiza esta validación es:

Si logramos abstraer nuestra mente de la sopa de letras de paréntesis,

vemos que la lógica es muy sencilla: ambos nulos o ambos no nulos.

Veamos un ejemplo más complejo. Tenemos un checkbox que permite

al usuario elegir realizar su pago en cuotas y un campo de texto donde el

usuario ingresa el número de cuotas. Necesitamos que el usuario ingrese

(((campo1 == null) and (campo2 == null)) or((campo1 != null) and (campo2 != null)))

C#_Struts_Validator.indd 15C#_Struts_Validator.indd 15 08/09/2014 10:4308/09/2014 10:43

Page 16: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR16

www.redusers.com

el número de cuotas solamente si marcó la opción de pagar en cuotas.

Veamos un ejemplo donde, además, de usar validwhen, lo mezclamos

con otros validadores para hacer un validador completo.

La porción de código de la página JSP:

Y el validador correspondiente:

<html:checkbox property=”cuotas” /><bean:message key=”form.cuotas” /><br/>

<bean:message key=”form.cantCuotas” />:<html:text property=”cantCuotas” size=”4” /><html:errors property=”cantCuotas” /><br/>

<!-- Validamos el campo cantCuotas con tres validadores -->

<fi eld property=”cantCuotas” depends=”validwhen, integer, intRange”> <!-- Argumento para los mensajes de error,

sirve tanto para integer como intRange -->

<arg key=”form.cantCuotas” position=”0” />

<!-- Argumentos para el mensaje de error del validador intRange -->

<arg name=”intRange” key=”${var:min}” resource=”false” position=”1” /> <arg name=”intRange” key=”${var:max}” resource=”false” position=”2” />

<!-- Mensaje a mostrar si falla el validador validwhen -->

<msg name=”validwhen” key=”form.cantCuotas.msg” />

<!-- Confi guración de validwhen -->

<var> <var-name>test</var-name> <var-value>((cuotas == null) or (*this* != null))</var-value>

C#_Struts_Validator.indd 16C#_Struts_Validator.indd 16 08/09/2014 10:4308/09/2014 10:43

Page 17: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 17

www.redusers.com

Vamos a repasar con detenimiento este validador. En primer lugar,

estamos asignando al campo tres validadores: validwhen, integer e intRange.

Esto signifi ca que las tres validaciones deben ser exitosas para que el cam-

po sea válido. En primer lugar, se ejecutará validwhen:

Esto implica que la validación será exitosa si cuotas es nulo (o sea, no

está marcado) o si cantCuotas no es nulo.

((cuotas == null) or (*this* != null))

Es una buena práctica mostrar los errores por duplicado. Primero, al principio de

la página, en un lugar bien visible, los mostramos todos juntos, y luego, en el lugar

específi co donde ocurrió cada error, los mostramos de a uno.

ERRORES POR DOQUIER

</var> <!-- Variables para confi gurar el validador intRange -->

<var> <var-name>min</var-name> <var-value>2</var-value> </var> <var> <var-name>max</var-name> <var-value>12</var-value> </var></fi eld>

C#_Struts_Validator.indd 17C#_Struts_Validator.indd 17 08/09/2014 10:4308/09/2014 10:43

Page 18: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR18

www.redusers.com

Si esta validación fue exitosa, se procederá a validar que lo ingresado

sea un número, y luego, que esté en el rango establecido.

Validación en el clienteLos validadores de Struts también traen consigo código JavaScript

para agregar a las páginas JSP. De esta forma, en los casos en que se

pueda, la validación se realizará del lado del cliente, mediante código

JavaScript.

Este enfoque tiene pros y contras. Su ventaja principal es que enviar

la información al servidor, que esta sea validada y que vuelva, en caso

de error, toma su tiempo. Si la conexión es lenta o si hay mucho tráfi co,

pueden pasar varios segundos hasta que el servidor nos conteste que

nos olvidamos de marcar una opción que no logramos ver. Usando có-

digo JavaScript y realizando la validación en el cliente, esto es práctica-

mente instantáneo: ningún tipo de información viaja por la red.

Como contras, tenemos varias, aunque menores. En primer lugar,

no podemos depender de este tipo de validaciones, ya que el usuario

puede haber elegido deshabilitar el código JavaScript en su navegador

o simplemente puede tener un navegador que no soporte este lengua-

je. Agregar código JavaScript incrementa el tamaño de la página. Este

incremento suele ser despreciable, pero es algo a considerar. Además,

muchas veces las validaciones necesitan intrínsecamente ser realizadas

en el servidor. La corroboración de un nombre de usuario y contraseña

claramente no podremos realizarla del lado del cliente.

A fi n de cuentas, la validación en el cliente es una importante herramienta

que ayuda al cliente a ahorrar tiempos, y, al servidor, a aliviar su carga.

Activar el código JavaScript Aplicar la validación en el cliente es muy sencillo. Veamos un pequeño

ejemplo al que aplicaremos validación JavaScript.

Dos acciones:

C#_Struts_Validator.indd 18C#_Struts_Validator.indd 18 08/09/2014 10:4308/09/2014 10:43

Page 19: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 19

www.redusers.com

El archivo XML que defi ne las validaciones (¡recordemos agregar este

archivo a la lista de pathnames del Validator PlugIn!):

<action path=”/cliente” name=”clienteForm” scope=”request” validate=”false” forward=”/jsp/capitulo8/cliente.jsp” />

<action path=”/cliente2” type=”capitulo8.action.ProcesarClienteAction” name=”clienteForm” scope=”request” validate=”true” input=”/cliente.do”></action>

<!DOCTYPE form-validation PUBLIC “-//Apache Software Foundation//DTD Commons Validator Rules Confi guration 1.1.3//EN” “http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd”>

<form-validation> <formset> <form name=”clienteForm”> <fi eld property=”nombre” depends=”required”> <arg key=”cliente.nombre” position=”0” /> </fi eld> <fi eld property=”edad” depends=”required, integer”> <arg key=”cliente.edad” position=”0” /> </fi eld> </form> </formset> </form-validation>

C#_Struts_Validator.indd 19C#_Struts_Validator.indd 19 08/09/2014 10:4308/09/2014 10:43

Page 20: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR20

www.redusers.com

Hasta ahora, todo como siempre. Suena lógico, y la parte de valida-

ción del cliente la realizaremos, como es de esperarse, en el cliente.

Veamos el código JSP de la página:

El tag html:javascript inserta el código JavaScript necesario para las vali-

daciones. Sus atributos son los siguientes:

• cdata: si es true (por defecto lo es), encierra el código JavaScript genera-

do en una sección CDATA, de forma de ser compatible con XML.

<%@ taglib uri=”/tags/struts-html” prefi x=”html” %>

<html:html>

<head><!-- Agregamos validación en el cliente -->

<html:javascript formName=”clienteForm” method=”validar” /></head>

<!-- Un método JavaScript para cuando el formulario es enviado -->

<html:form action=”cliente2” onsubmit=”return validar(this);”>

Nombre: <html:text property=”nombre” /><html:errors property=”nombre” /><br/>Edad: <html:text property=”edad” /><html:errors property=”edad” /><br/>

<html:submit value=”Enviar” /><html:cancel value=”Cancelar” />

</html:form>

</html:html>

C#_Struts_Validator.indd 20C#_Struts_Validator.indd 20 08/09/2014 10:4308/09/2014 10:43

Page 21: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 21

www.redusers.com

• htmlComment: si es true (por defecto lo es), encierra el código

JavaScript en comentarios.

• formName: nombre del formulario a validar.

• method: nombre del método JavaScript que realizará la validación.

Si no especifi camos este parámetro, el valor por defecto es

validate[formName]. En el ejemplo, hubiera sido: validateClienteForm.

• page: número de página que estamos validando, para validaciones

multipágina.

• scriptLanguage: si es true (por defecto), se agrega el atributo language

al elemento <script>.

• src: el atributo src del elemento <script>.

• staticJavascript: si es true (por defecto), el código JavaScript estático

es agregado a la página.

• dynamicJavascript: si es true (por defecto), el código JavaScript dinámico

es agregado a la página.

Los atributos staticJavascript y dynamicJavascript ameritan una explicación

extra. El código estático se refi ere a las funciones JavaScript genéricas

validadoras, funciones como validateRequired o validateInteger, que son las

asociadas a los validadores. El código dinámico es el que llama a estas

funciones en base a lo que el formulario requiera.

En nuestro caso, el código dinámico será el encargado de llamar a las

funciones que validen que los campos no estén vacíos y que el campo

edad, además, sea numérico.

El tag Logic:messagesPresent resulta muy útil si lo que queremos es mostrar cierto

código, solo en los casos en que arroje mensajes de error. De esta forma, podemos crear

tablas que los contengan y, si no existen errores, no nos encontraremos con una tabla vacía.

LOGIC:MESSAGESPRESENT

C#_Struts_Validator.indd 21C#_Struts_Validator.indd 21 08/09/2014 10:4308/09/2014 10:43

Page 22: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR22

www.redusers.com

Por defecto, ambos códigos son generados. Podríamos crear una página

que se use para generar el código estático y guardarlo como un archivo

o que las páginas con validaciones incluyan el contenido.

Si generamos solo el código estático, no es necesario especifi car un form:

En este ejemplo, generamos el código estático que podremos incluir

o referenciar desde cualquier página.

Además de incluir el código JavaScript, necesario para las validaciones

en el cliente, debemos llamar al código cuando se envía el formulario para

que la validación efectivamente se ejecute. En el ejemplo, hicimos:

El atributo onsubmit especifi ca código JavaScript a ejecutar cuando el

formulario es enviado. La función validar (que toma ese nombre porque

así lo defi nimos usando el atributo method en el tag html:javascript) de-

vuelve un resultado booleano. Si el resultado es falso, el formulario no

se envía al servidor. En la Figura 1 vemos el validador en acción.

<html:javascript dynamicJavascript=”false” staticJavascript=”true” />

<html:form action=”cliente2” onsubmit=”return validar(this);”>

Cuando un campo necesita una validación automática y otra que involucre lógica

de negocios (por ejemplo, un nombre de usuario no vacío y que no exista en la base de

datos), tenemos que considerar si queremos hacer ambas validaciones en la acción

o separarlas, para mostrarle al usuario todos los errores juntos y que los pueda

corregir, sin necesidad de enviar el formulario varias veces.

DOBLE VALIDACIÓN

C#_Struts_Validator.indd 22C#_Struts_Validator.indd 22 08/09/2014 10:4308/09/2014 10:43

Page 23: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 23

www.redusers.com

Si incluimos en la página un botón de cancelación (como en nuestro

ejemplo), no necesitamos agregar código extra, ya que el botón trae gene-

rado un código JavaScript para saltear la validación. Al cancelar el formu-

lario lo estamos enviando, pero no queremos que sea validado.

Figura 1. Con las validaciones JavaScript fácilmentemejoramos la validación de datos para el usuario.

Un validador propioMediante los validadores del proyecto Commons Validator –en

conjunción con validwhen– podemos realizar una gran cantidad de vali-

daciones de uso recurrente. Pero, en el caso de necesitar una validación

que no esté al alcance de estas herramientas, podemos fácilmente pro-

gramarla y usarla como cualquier otra validación.

Es más efi ciente programar un validador propio una vez que sepamos, de antemano,

que vamos a usarlo varias veces en nuestra aplicación. No tiene mucho sentido crear un

validador para cada caso particular que necesitemos y que termine siendo usado solo

una vez; en esos casos, es preferible sobrescribir el método validate del ActionForm.

ANTES DE CREAR UN VALIDADOR PROPIO

C#_Struts_Validator.indd 23C#_Struts_Validator.indd 23 08/09/2014 10:4308/09/2014 10:43

Page 24: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR24

www.redusers.com

En los archivos de confi guración de validaciones, donde veníamos

defi niendo los validadores para los campos de formularios, podemos

agregar nuestros propios validadores. Dentro del elemento global (que

debe defi nirse antes que el elemento formset), el elemento validator espe-

cifi ca un validador.

Si miramos el archivo validator-rules.xml que trae Struts, veremos que

consta básicamente de las declaraciones de los validadores que hemos es-

tado viendo durante el capítulo. Los atributos a defi nir en el elemento son:

• name: nombre del validador.

• classname: clase que implementa la validación.

• method: nombre del método que implementa la validación.

• methodParams: parámetros que recibe el método.

• depends: validadores de los que depende este validador, separados

por coma. Estos validadores son llamados antes que el actual.

• msg: clave del mensaje de error que se mostrará si la validación falla.

Si bien un validador puede defi nir por defecto una clave de mensaje

a mostrar, siempre podemos redefi nir el mensaje para cada validación

particular mediante el elemento msg. Por ejemplo, el validador required

defi ne como clave errors.required, pero podemos defi nir un validador

sobre un campo que use required y redefi na el mensaje:

Volviendo al tema de los validadores propios, veamos cómo es la

defi nición de nuestro propio validador, encargado de verifi car que

el valor de un campo sea un número primo.

<fi eld property=”nombre” depends=”required”>

<arg position=”0” key=”proyecto.nombre” />

<msg key=”mensaje.propio”/>

</fi eld>

C#_Struts_Validator.indd 24C#_Struts_Validator.indd 24 08/09/2014 10:4308/09/2014 10:43

Page 25: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 25

www.redusers.com

Los parámetros que recibe el método que implementa la validación de-

ben respetar esta aridad. Struts asume que todo método validador recibirá

estos parámetros y de esta manera los invoca.

El validador depende de integer, ya que, para verifi car que el campo sea

un número primo, primeramente debe ser número.

Veamos la clase que implementa el método que realiza la validación:

<global>

<validator name=”primo”

classname=”capitulo8.validador.Validador”

method=”validarPrimo”

methodParams=”java.lang.Object,

org.apache.commons.validator.ValidatorAction,

org.apache.commons.validator.Field,

org.apache.struts.action.ActionMessages,

org.apache.commons.validator.Validator,

javax.servlet.http.HttpServletRequest”

depends=”integer”

msg=”error.primo”/>

</global>

package capitulo8.validador;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.validator.Field;

import org.apache.commons.validator.GenericValidator;

import org.apache.commons.validator.Validator;

import org.apache.commons.validator.ValidatorAction;

import org.apache.commons.validator.util.ValidatorUtils;

import org.apache.struts.action.ActionMessages;

C#_Struts_Validator.indd 25C#_Struts_Validator.indd 25 08/09/2014 10:4308/09/2014 10:43

Page 26: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR26

www.redusers.com

import org.apache.struts.validator.Resources;

public class Validador {

/**

* Verifi ca que el valor sea un número primo

*

* @param bean: El bean sobre el que efectuamos la validación

* @param va: La acción de validación que se está efectuando

* @param fi eld: El campo perteneciente al bean que queremos validar

* @param errors: Una lista de errores a la que agregaremos

los nuestros de ser necesario

* @param validator: El validador actual que está ejecutando la validación

*@param request: El pedido

*/

public static Object validarPrimo(Object bean, ValidatorAction va,

Field fi eld, ActionMessages errors, Validator validator,

HttpServletRequest request) {

/* Podemos devolver un objeto de tipo Boolean indicando si la validación

falló, o bien un objeto cualquiera no nulo para indicar validación

exitosa, o nulo para indicar validación fallida */

Object result = null;

// Obtenemos el valor del campo del bean

String value = ValidatorUtils.getValueAsString(bean, fi eld

.getProperty());

/* No requerimos valor, pero, si existe, que sea un número primo */

if (!GenericValidator.isBlankOrNull(value)) {

try {

C#_Struts_Validator.indd 26C#_Struts_Validator.indd 26 08/09/2014 10:4308/09/2014 10:43

Page 27: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 27

www.redusers.com

// Obtenemos el valor numérico

int valor = Integer.parseInt(value);

if (esPrimo(valor)) { /* Es primo, devolvemos un objeto no nulo,

indicando validación exitosa */

result = new Integer(valor); } else { /* Es compuesto, agregamos el error a la lista */

errors.add(fi eld.getKey(), Resources.getActionMessage( validator, request, va, fi eld)); }

}

catch (Exception e) {

/* No debería ocurrir nunca, ya que dependemos del validador

integer, pero igualmente agregamos el error */

errors.add(fi eld.getKey(), Resources.getActionMessage(

validator, request, va, fi eld));

}

}

return result; }

/**

* Devuelve si el entero es primo

*/

private static boolean esPrimo(int n) { if (n < 2) { return false;

}

C#_Struts_Validator.indd 27C#_Struts_Validator.indd 27 08/09/2014 10:4308/09/2014 10:43

Page 28: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR28

www.redusers.com

Validaciones multipáginaSi tenemos un formulario muy extenso, podemos particionarlo en

varias páginas y mostrar solo algunos campos en cada página para fa-

cilitar la navegación al usuario. Esto presenta un problema para la vali-

dación: si validamos todo el formulario en cada página, estaremos apli-

cando la validación a solo una parte del form. Si separamos los campos

en dos formularios distintos, podremos validar cada página correcta-

mente, pero nos veremos obligados a partir también la acción en dos,

cuando probablemente queramos todos los datos juntos.

Para solucionar este inconveniente, contamos con el atributo page. En

cada elemento fi eld correspondiente a un campo del formulario, podemos

especifi car a qué página de un formulario multipágina corresponde. De-

bemos, a su vez, proveer un atributo page indicando el número de página

para cada una. La validación se efectuará para todos los campos con nú-

mero de página menor o igual a la página actual. Esto implica que las

if ((n & 1) == 0) {

return true;

}

int raiz = (int) Math.sqrt(n);

for (int i = 3; i <= raiz; i += 2) {

if (n % i == 0) {

return false;

}

}

return true;

}

}

C#_Struts_Validator.indd 28C#_Struts_Validator.indd 28 08/09/2014 10:4308/09/2014 10:43

Page 29: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 29

www.redusers.com

primeras páginas serán validadas nuevamente en las siguientes páginas,

ya que se validan todos los atributos hasta la página actual.

Veamos un ejemplo con un formulario en dos páginas. El form es un

LazyValidatorForm. Defi nimos tres acciones:

<!-- Muestra la primera página -->

<action path=”/wizard1” name=”wizardForm” validate=”false” forward=”/jsp/capitulo8/wizard1.jsp” />

<!-- Valida la primera página y muestra la segunda -->

<action path=”/wizard2” name=”wizardForm” scope=”request” validate=”true” input=”/jsp/capitulo8/wizard1.jsp” forward=”/jsp/capitulo8/wizard2.jsp” />

<!-- Valida la primera y segunda página y ejecuta

la acción si la validación fue exitosa -->

<action path=”/procesarWizardForm” type=”capitulo8.action.ProcesarWizardAction” name=”wizardForm” scope=”request” validate=”true” input=”/jsp/capitulo8/wizard2.jsp”></action>

Una buena práctica es usar los métodos de validación del proyecto Commons Validator en

nuestras validaciones propias, cuando sea posible, para asegurarnos de emplear código ya

probado. La página web del proyecto es: http://jakarta.apache.org/commons/validator.

COMMONS VALIDATOR EN VALIDACIONES PROPIAS

C#_Struts_Validator.indd 29C#_Struts_Validator.indd 29 08/09/2014 10:4308/09/2014 10:43

Page 30: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR30

www.redusers.com

El código de la primera página:

Y el de la segunda:

<%@ taglib uri=”/tags/struts-html” prefi x=”html” %>

<html:html xhtml=”true”>

<html:form action=”wizard2”>

Nombre: <html:text property=”nombre” /><htm-l:errors property=”nombre” /><br/>

Apellido: <html:text property=”apellido” /><htm-l:errors property=”apellido” /><br/>

<!-- Atributo importante para el validador -->

<html:hidden property=”page” value=”0” />

<html:submit />

</html:form>

</html:html>

<%@ taglib uri=”/tags/struts-html” prefi x=”html” %><%@ taglib uri=”/tags/struts-bean” prefi x=”bean” %>

<html:html xhtml=”true”>

<html:form action=”procesarWizardForm”>

Correo electr&oacute;nico: <html:text property=”email” /><html:errors property=”email” /><br/>

C#_Struts_Validator.indd 30C#_Struts_Validator.indd 30 08/09/2014 10:4308/09/2014 10:43

Page 31: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 31

www.redusers.com

Notemos cómo se utiliza el atributo page, que es enviado al servidor

como un atributo más y es usado por el validador para saber qué pági-

na es la que se necesita validar. Notemos también que, en la segunda

página, guardamos los valores que el usuario ingresó en la primera.

De no hacer esto, la segunda página solo enviaría los atributos email,

dir y page, y el validador, al recibir estos datos, intentará validar todos

los campos con código de página menor o igual a 1 (y esto incluye tam-

bién nombre y apellido), y la validación, por lo tanto, fallaría.

Direcci&oacute;n: <html:textarea rows=”3” cols=”30” property=”dir” /><html:errors property=”dir” /><br/>

<!-- Atributo importante para el validador -->

<html:hidden property=”page” value=”1” />

<html:hidden property=”nombre” /><html:hidden property=”apellido” />

<html:submit />

</html:form>

</html:html>

Son formularios muy extensos, por lo que, idealmente, deberíamos brindar al usuario la

posibilidad de guardar lo hecho hasta el momento para que pueda proseguir más tarde.

Usando el enfoque visto en el ejemplo con el bean DatosForm, podríamos ir guardando

en sesión o en alguna base de datos lo ingresado para, una vez obtenido todo, procesarlo.

FORMULARIOS MULTIPÁGINA

C#_Struts_Validator.indd 31C#_Struts_Validator.indd 31 08/09/2014 10:4308/09/2014 10:43

Page 32: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR32

www.redusers.com

La acción que maneje este pedido recibirá los cuatro atributos.

Una alternativa a ir guardando los valores anteriores en campos hidden

sería, en las acciones intermedias, ir guardando los valores en sesión

(dentro de un bean, por ejemplo). Veamos cómo sería la acción interme-

dia correspondiente al ejemplo:

package capitulo8.action;

import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionForward;import org.apache.struts.action.ActionMapping;import org.apache.struts.validator.LazyValidatorForm;

public class Wizard1Action extends Action {

public ActionForward execute(ActionMapping map, ActionForm form, HttpServletRequest req, HttpServletResponse res) throws Exception {

LazyValidatorForm dyna = (LazyValidatorForm) form; String nombre = (String) dyna.get(“nombre”); String apellido = (String) dyna.get(“apellido”); // El bean donde guardamos los datos

DatosWizard dw = new DatosWizard(); dw.setNombre(nombre); dw.setApellido(apellido); req.getSession().setAttribute(“DatosWizard”, dw); return map.fi ndForward(“ok”); }}

C#_Struts_Validator.indd 32C#_Struts_Validator.indd 32 08/09/2014 10:4308/09/2014 10:43

Page 33: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 33

www.redusers.com

Mostrar errores con estiloHemos visto en los ejemplos que, usando el tag html:errors, podemos

mostrar los errores de validación ocurridos en la página o respecto a un

campo en particular. Este tag posee muchas opciones en cuanto al esti-

lo y la forma de mostrar los errores. Además del atributo property –que,

al usarlo, devuelve solo los errores para la propiedad dada–, hay cuatro

atributos extra asociados con el estilo del error:

• header: clave de lo que se imprimirá antes de todos los errores.

• footer: clave de lo que se imprimirá después de todos los errores.

• prefi x: clave de lo que se imprimirá antes de cada error.

• suffi x: clave de lo que se imprimirá después de cada error.

Si no especifi camos estos atributos, los valores por defecto son:

errors.header, errors.footer, errors.prefi x y errors.suffi x, respectivamente.

Usando estos atributos, veamos un ejemplo no muy estético (pero fun-

cional) de errores con estilos aplicados:

<%@ taglib uri=”/tags/struts-html” prefi x=”html” %>

<html:html>

<html:form action=”cliente2”>

<html:errors header=”errors.table.header” footer=”errors.table.footer” prefi x=”errors.table.prefi x” suffi x=”errors.table.suffi x” />

<h2>Ingrese sus datos</h2>

Nombre: <html:text property=”nombre” /><html:errors property=”nombre” />

C#_Struts_Validator.indd 33C#_Struts_Validator.indd 33 08/09/2014 10:4308/09/2014 10:43

Page 34: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR34

www.redusers.com

Este código es prácticamente igual (excepto por la parte de valida-

ción JavaScript) que el anterior; solamente agregamos un tag para mos-

trar todos los errores juntos antes de los campos, y, además, los cam-

pos mostrarán su error específi co, si hubiera.

La porción correspondiente al archivo MessageResources.properties:

El resultado de esta obra de arte posmoderno de diseño web, en la Figu-

ra 2. También podemos combinar esta técnica con los atributos errorStyle

o errorStyleClass de los campos, resaltando aún más la ubicación del error.

errors.table.header=<table style=”background-color:yellow;color:red;border:1px solid #217C31;”>errors.table.footer=</table>errors.table.prefi x=<tr><td width=”300” align=”center”><b>errors.table.suffi x=</b></td></tr>

errors.header=<span style=”background-color:yellow;color:red;border:1px solid #217C31;”>errors.footer=</span>errors.prefi x=&nbsp;&rarr;&nbsp;errors.suffi x=&nbsp;&larr;&nbsp;

<br/>

Edad: <html:text property=”edad” /><html:errors property=”edad” /><br/>

<html:submit value=”Enviar” /></html:form>

</html:html>

C#_Struts_Validator.indd 34C#_Struts_Validator.indd 34 08/09/2014 10:4308/09/2014 10:43

Page 35: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 35

www.redusers.com

Figura 2. Usando atributos del tag, podemos resaltarmás los errores y hacerlos visibles para el usuario.

El ejemplo completoVeamos un ejemplo completo, usando todas las validaciones que vimos

en este apéndice, tanto las de Struts como las propias.

La página JSP:

<%@ taglib uri=”/tags/struts-html” prefi x=”html” %>

<%@ taglib uri=”/tags/struts-bean” prefi x=”bean” %>

<html:html xhtml=”true”>

<html:form action=”procesarValidatorForm” focus=”nombre”>

<bean:message key=”form.nombre” />:

<html:text property=”nombre” /><html:errors property=”nombre” /><br/>

<bean:message key=”form.cp” />:

<html:text property=”cp” /><html:errors property=”cp” /><br/>

<bean:message key=”form.edad” />:

<html:text property=”edad” /><html:errors property=”edad” /><br/>

C#_Struts_Validator.indd 35C#_Struts_Validator.indd 35 08/09/2014 10:4308/09/2014 10:43

Page 36: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR36

www.redusers.com

<bean:message key=”form.sueldo” />:

<html:text property=”sueldo” /><html:errors property=”sueldo” /><br/>

<bean:message key=”form.fecha_nacimiento” />:

<html:text property=”fecha_nacimiento” /><html:errors

property=”fecha_nacimiento” /><br/>

<bean:message key=”form.litros” />:

<html:text property=”litros” /><html:errors property=”litros” /><br/>

<bean:message key=”form.tarjeta” />:

<html:text property=”tarjeta” /><html:errors property=”tarjeta” /><br/>

<bean:message key=”form.correo” />:

<html:text property=”correo” /><html:errors property=”correo” /><br/>

<bean:message key=”form.url” />:

<html:text property=”url” size=”50” /><html:errors property=”url” /><br/>

<html:checkbox property=”cuotas” /><bean:message key=”form.cuotas” /><br/>

<bean:message key=”form.cantCuotas” />:

<html:text property=”cantCuotas” size=”4”

/><html:errors property=”cantCuotas” /><br/>

Campos amigos:<br/>

<html:text property=”campo1” />

<html:text property=”campo2” /><html:errors property=”campo1” /><br/>

<bean:message key=”form.n” />:

<html:text property=”n” size=”4” /><html:errors property=”n” /><br/>

C#_Struts_Validator.indd 36C#_Struts_Validator.indd 36 08/09/2014 10:4308/09/2014 10:43

Page 37: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 37

www.redusers.com

<html:javascript formName=”validatorForm” />

<html:submit />

</html:form>

</html:html>

El archivo validator-form.xml con las validaciones:

<!DOCTYPE form-validation PUBLIC

“-//Apache Software Foundation//DTD Commons Validator

Rules Confi guration 1.1.3//EN”

“http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd”>

<form-validation>

<global>

<validator name=”primo”

classname=”capitulo8.validador.Validador”

method=”validarPrimo”

methodParams=”java.lang.Object,

org.apache.commons.validator.ValidatorAction,

org.apache.commons.validator.Field,

org.apache.struts.action.ActionMessages,

org.apache.commons.validator.Validator,

javax.servlet.http.HttpServletRequest”

depends=”integer”

msg=”error.primo”/>

</global>

C#_Struts_Validator.indd 37C#_Struts_Validator.indd 37 08/09/2014 10:4308/09/2014 10:43

Page 38: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR38

www.redusers.com

<formset>

<form name=”validatorForm”>

<fi eld property=”nombre” depends=”required, minlength”>

<arg key=”form.nombre” position=”0” />

<arg name=”minlength” key=”${var:minlength}”

resource=”false” position=”1” />

<var>

<var-name>minlength</var-name>

<var-value>5</var-value>

</var>

</fi eld>

<fi eld property=”cp” depends=”mask”>

<msg name=”mask” key=”form.cp.msg”/>

<arg key=”form.cp” position=”0” />

<var>

<var-name>mask</var-name>

<var-value>^[a-zA-Z]{3}[0-9]{4}$</var-value>

</var>

</fi eld>

<fi eld property=”edad” depends=”integer”>

<arg key=”form.edad” position=”0” />

</fi eld>

<fi eld property=”sueldo” depends=”double”>

<arg key=”form.sueldo” position=”0” />

</fi eld>

C#_Struts_Validator.indd 38C#_Struts_Validator.indd 38 08/09/2014 10:4308/09/2014 10:43

Page 39: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 39

www.redusers.com

<fi eld property=”fecha_nacimiento” depends=”date”> <arg key=”form.fecha_nacimiento” position=”0” /> <var> <var-name>datePattern</var-name> <var-value>dd/MM/yyyy</var-value> </var> </fi eld>

<fi eld property=”litros” depends=”integer, intRange”> <arg key=”form.litros” position=”0” /> <arg name=”intRange” key=”${var:min}” resource=”false” position=”1” /> <arg name=”intRange” key=”${var:max}” resource=”false” position=”2” /> <var> <var-name>min</var-name> <var-value>4</var-value> </var> <var> <var-name>max</var-name> <var-value>24</var-value> </var> </fi eld> <fi eld property=”tarjeta” depends=”creditCard”> <arg key=”form.tarjeta” position=”0” /> </fi eld>

<fi eld property=”correo” depends=”email”> <arg key=”form.correo” position=”0” /> </fi eld> <fi eld property=”url” depends=”url”>

C#_Struts_Validator.indd 39C#_Struts_Validator.indd 39 08/09/2014 10:4308/09/2014 10:43

Page 40: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR40

www.redusers.com

<arg key=”form.url” position=”0” /> <var> <var-name>nofragments</var-name> <var-value>true</var-value> </var> <var> <var-name>schemes</var-name> <var-value>http,https</var-value> </var> </fi eld>

<fi eld property=”cantCuotas” depends=”validwhen, integer, intRange”> <arg key=”form.cantCuotas” position=”0” /> <arg name=”intRange” key=”${var:min}” resource=”false” position=”1” /> <arg name=”intRange” key=”${var:max}” resource=”false” position=”2” />

<msg name=”validwhen” key=”form.cantCuotas.msg”/>

<var> <var-name>test</var-name> <var-value>((cuotas == null) or (*this* != null))</var-value> </var> <var> <var-name>min</var-name> <var-value>2</var-value> </var> <var> <var-name>max</var-name> <var-value>12</var-value>

C#_Struts_Validator.indd 40C#_Struts_Validator.indd 40 08/09/2014 10:4308/09/2014 10:43

Page 41: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

DESARROLLO WEB CON JAVA DESDE CERO 41

www.redusers.com

</var> </fi eld>

<fi eld property=”campo1” depends=”validwhen”> <msg name=”validwhen” key=”form.campos.amigos” /> <var> <var-name>test</var-name> <var-value>(((campo1 == null) and (campo2 == null)) or ((campo1 != null) and (campo2 != null)))</var-value> </var> </fi eld>

<fi eld property=”n” depends=”primo”> <arg key=”form.n” position=”0” /> </fi eld>

</form>

</formset>

</form-validation>

En este capítulo comprendimos el poder de las validaciones de Struts. Añadimos

validaciones predefi nidas a nuestros campos, defi nimos validaciones complejas usan-

do validwhen e implementamos nuestras propias validaciones. Agregamos, también,

validación del lado del cliente y personalizamos los mensajes de error.

RESUMEN

Este ejemplo completo lo podemos realizar en el entorno de ECLIPSE.

C#_Struts_Validator.indd 41C#_Struts_Validator.indd 41 08/09/2014 10:4308/09/2014 10:43

Page 42: C# Struts Validatorpremium.redusers.com.s3.amazonaws.com/LIBROS... · En el Capítulo 5 vimos cómo programar nuestros objetos ActionForm para que se validen los datos ingresados

APÉNDICE C. STRUTS VALIDATOR42

www.redusers.com

PARTE TEÓRICA

1 ¿Cuál es la utilidad de las validaciones en las páginas web?

2 ¿Cuál es la diferencia entre datePattern y datePatternStrict en la validación por fecha? ¿En qué caso usaría cada validador?

PARTE PRÁCTICA

1 Agregue validación al proyecto del juego Ahorcado que utilizamos en capítulos anteriores.

2 Cree un validador para el juego del Ahorcado, que valide que se ingrese una y solo una letra en el campo, usando el validador mask.

3 Cree un validador para el Ahorcado, que valide que se ingrese una y solo una letra en el campo, implementando un validador propio.

4 ¿Es válida la siguiente expresión booleana del validador validwhen?: ((*this* == null) or (campo1 != null) or (campo2 != null))

5 ¿Qué validación realiza la siguiente expresión en un validador validwhen?: (((cant >= 60) and (cant <= 100)) or (*this* == null))

Si tiene alguna consulta técnica relacionada con el contenido, puede contactarse

con nuestros expertos: [email protected].

PROFESOR EN LÍNEA

Actividades

C#_Struts_Validator.indd 42C#_Struts_Validator.indd 42 08/09/2014 10:4308/09/2014 10:43