viernes, 25 de septiembre de 2009

Validator en JSF

Este último més he estado trabajando en una aplicación sobre JSF, una tecnología que bajo mi punto de vista todavía le queda para ser madura, sobre todo por la cantidad de framework que puedes usar pero que luego mezclarlos es un verdadero dolor de cabezas. Despues de investigar ICEFace el cual me gustó mucho, ahora tenías que usar tiles para poder incluyectarle trozos y poder crear plantilla. Total que al final uso MyFaces (implementación de Apache de JSF) con Tomahawk que parece ser el más tolerante.


Entonces he descubierto muchas de las bondades de JSF entre ellas los validadores, unas clases java que te sirven para la validación de campos en los formularios, pudiendote olvidar del javascript. Esto me ha gustado mucho pero me encontre un escoyo que me gustaría ilustrar. Tenía un campo Año que quería validar. Bien pues cree el validador correspondiente:


public void validate(FacesContext facesContext, UIComponent uiComponent, Object object) throws ValidatorException {

try {

int anio = Integer.parseInt(object.toString());

if (anio < 1960 || anio > 2050) {



FacesMessage message = new FacesMessage();

message.setSummary("Año "+anio+" no válido");

throw new ValidatorException(message);

}

} catch (Exception e) {


FacesMessage message = new FacesMessage();

message.setSummary("Año "+object.toString()+" no válido");

throw new ValidatorException(message);

}

}



Y lo dí de alta en el faces-config.xml

<validator>

<validator-id>ValidaAnio</validator-id>

<validator-class>Validadores.ValidaAnio</validator-class>

</validator>

Ahora el problema es que al validar un campo:

<t:outputText id="Anyo" value="Año(aaaa):"/>

<t:inputText id="iAnyo" size="4" maxlength="4" value="#{ActasBusquedaBB.anyo}">

<f:validator validatorId="ValidaAnio"/>

</t:inputText>



pues el campo dentro del formulario se quedaba relleno con el valor erroreo.

Por ejemplo, si en el input anterior introduzco "abcd" como no es un año este falla en el validador
al hacer el casting a entero y sale el mensaje de "Año abcd no válido", pero no se borra el campo del formulario.

La pregunta es ¿ Como hacer desde la clase java ValidaAnio que el campo del formulario se borre si el valor es incorrecto?

Bien pues se hace en 2 lineas pero encontrarlas me costo sangre y por eso la pongo aquí.

public void validate(FacesContext facesContext, UIComponent uiComponent, Object object) throws ValidatorException {

try {

int anio = Integer.parseInt(object.toString());

if (anio < 1960 || anio > 2050) {

if (uiComponent instanceof UIInput)

((UIInput)uiComponent).setSubmittedValue("");

FacesMessage message = new FacesMessage();

message.setSummary("Año "+anio+" no válido");

throw new ValidatorException(message);

}

} catch (Exception e) {

if (uiComponent instanceof UIInput)

((UIInput)uiComponent).setSubmittedValue("");

FacesMessage message = new FacesMessage();

message.setSummary("Año "+object.toString()+" no válido");

throw new ValidatorException(message);

}

}



Espero que os sirva ;)

3 comentarios:

Adust Jed dijo...

Saludos,

ey man parece que el codigo esta errado en el ejemplo en donde supuestamente no borra el valor del campo.

Si las lineas que agregaste son:

if (uiComponent instanceof UIInput)

((UIInput)uiComponent).setSubmittedValue("");

En el primer ejemplo de codigo la tienes incluida en el catch, asi que el comentario que pones de ejemplo con el "abcd" estaria errado, dado que si borraria el valor erroneo del campo.

Con el ICEFaces puedes crear plantillas usando Facelets.

Un saludo.

Jorge Cantón Ferrero dijo...

LLevas razón Adust Jed, al borrar la parte de código que accedía al componente en la primera versión, se me olvido quitarlo también del "catch".

Y lo que comentas de Facelets, también lo intente pero me parecía muy bestia meter Facelets para solo usar un tag que era el necesario para incluir trozos. Creo que no debería ser así y que ICEFaces debería implementar su propio mecanismo.

Un saludo ;)

Adust Jed dijo...

Saludos,

si el template no es muy complejo no vale la pena intentar hacerlo con Facelets. Por otro lado, Facelets es un poco engorroso, pero porque se busca la creacion de componentes como tal para hacer mas facil la reutilizacion y otro par de cositas mas.

Comparto lo que dices de ICEFaces, aunque suele ser una buena opcion para hacer aplicaciones rapidamente. Dado que tiene mayor variedad de componentes y hay mucho definido, MyFaces me parece mas para el man inquieto que quiere hacer las cosas por el mismo o que busca hacerse su propio framework, en ese aspecto es muchisimo mas flexible que icefaces.