domingo, 27 de septiembre de 2009

Obtener objetos de la session en JSF

Otro de los descubrimientos que he realizado tras trabajar en el último proyecto sobre JSF ha sido obtener instancias de objetos o variables creadas por el contenedor web. Como sabéis todos las clases java que utilices para trabajar con JSF (Backing bean, JavaBean...) deben estar dadas de alta en el faces-config.xml y deben de tener un constructor público sin argumentos. Esto es debido a que el contenedor de aplicaciones web (Tomcat, Glassfish ...) crearán instancias de estas clases para cada session (según el ambito especificado en faces-config.xml), esto plantea algunos problemas al querer usar singleton o simplemente al querer comunicar estas instancias de objetos ya que no existen referencias entre estas clases.

Bien pues desde cualquier clase java puedes escribir las siguientes líneas y obtendrás el valor de los atributos de otra instancia de las clases creadas por el contenedor.

FacesContext fc = FacesContext.getCurrentInstance();

String usr_id = (String)fc.getApplication().createValueBidding("#SessionScope.usr_id").getValue(fc);


Espero que os sea de utilidad a mi me ha venido de perlas.

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 ;)