domingo, 28 de noviembre de 2010

INICIO JSF


PRIMER CONTACTO


Proyecto: ejemplojsf
Implementacion: richfaces 3.3.2
http://livedemo.exadel.com/richfaces-demo/richfaces/tabPanel.jsf

JSF es MVC
utiliza Spring para el arranque de SessionFactory (Hibernate) e inyeccion de dependencias

Archivo de configuración
faces-config.xml

http://docs.google.com/View?id=dvcsqmx_170hk5nmkfd

http://docs.google.com/View?id=dvcsqmx_168gqrsqmxb


Tutorial: http://dl.dropbox.com/u/11610758/manual-jsf.pdf



DETALLES DE LA CONFIGURACION

El enlace JSF-SPRING para que los beans definidos en el contexto de spring puedan ser inyectados como “managed-property” en un “managed-bean” de jsf es gracias a
haber añadido como variable resolver de jsf:

<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>



ALGUNOS ASPECTOS IMPORTANTES DE JSF

  • CAMBIO DE PÁGINA CON BOTÓN:
No siempre es necesario invocar a un método para activar la regla de navegación. Esto sólo será necesario para una navegación dinámica donde, dependiendo de alguna condición, saltaremos a una página o a otra. Si la navegación es estática, es decir siempre saltamos a la misma página, no haría falta implementar ningún método, y bastaría con poner:

<h:commandButton value="#{msg.showPreview}" action="success" />


POR SUPUESTO EL ACTION DEBE ESTAR DENTRO DE LA ETIQUETAS:
  1. <f:view>
  2. <h:form>

  • EVENTO ASOCIADO A UN BOTÓN:

Podemos ver este tipo de eventos como acciones que implican cambios sobre la interfaz de usuario.

Tenemos el ejemplo del botón “Desactivar configuración de color”. Cuando el usuario pulse este botón se desactivarán las listas desplegables que hay sobre él, y cambia el texto del propio botón a “Activar configuración de color”.

<h:commandButton value="#{resumeBean.colorSupportLabel}"
actionListener="#{resumeBean.toggleColorSupport}"
immediate="true" />

Para conseguir que cambie le texto se puede ver como, en vez de usar directamente i18n, le pedimos el valor al propio bean con “#{resumeBean.colorSupportLabel}”.

Con “immediate='true'” conseguimos que no se ejecuten las validaciones.

Con el atributo “actionListener” estamos definiendo quien atenderá el evento cuando se pulse el botón. En nuestro ejemplo es el método “toggleColorSupport” del bean “resumeBean”. Este tipo de métodos no devuelven nada y tienen un único parámetro de tipo “ActionEvent”.

public void toggleColorSupport(ActionEvent event) {
isColorSupported = !isColorSupported;
}

Este método simplemente cambia el valor de la propiedad “isColorSupported”. El valor de esta propiedad es consultado cuando se va a pintar la lista de selección, en el atributo “disabled”:


<h:selectOneMenu id="fgColor"
value="#{resumeBean.fgColor}"
disabled="#{!resumeBean.colorSupported}">
<f:selectItems value="#{resumeBean.availableColors}" />
</h:selectOneMenu>


  • CONTEXTO, SESION Y REQUEST:

ACCEDER A SESION


Tienes que crear un Bean para hacer esto. Por ejemplo uno llamado "UsuarioBean". En este Bean puede acceder a la sesión del contexto con:

(HttpSession) getCurrentInstance().getExternalContext().getSession(false)

Tienes que declarar el Bean en el faces-config.xml

<managed-bean>
<managed-bean-name>usuarioBean</managed-bean-name&g t;
<managed-bean-class>com.organizacion.proyecto.vista.Us uarioBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

Y luego hacer uso de este Bean en el JSF:

<h:commandLink action="#{usuarioBean.logout}">Cerrar sesión</h:commandLink>
<h:commandButton id="aceptar" action="#{usuarioBean.login}" value="Login" />


Una posible forma de cerrar la sesion:

HttpSession session = (HttpSession)facesContext.getExternalContext().getSession(false);
if (session != null)
{
session.invalidate(); //CERRAR SESION
}


¿Cuál es la diferencia entre getSession (true) y getSession (false)?

--getSession(true): va a comprobar si ya hay una sesión vigente para el usuario. Si existe sesión, se devolverá ese objeto de sesión, de lo contrario se creará un objeto de sesión explícitamente y lo devolverá al cliente.

--getSession(false): va a comprobar si existe una sesión. En caso afirmativo, devolverá la referencia de ese objeto de sesión, de lo contrario, null.


ACCEDER A CONTEXTO

FacesContext facesContext= FacesContext.getCurrentInstance();


ACCEDER AL REQUEST

HttpServletRequest request =(HttpServletRequest) facesContext.getExternalContext().getRequest();

  1. PARÁMETROS: Enumeration params = request.getParameterNames();
  2. SESIÓN HTTP: HttpSession session = request.getSession();


ACCESO A PARÁMETROS

Existen dos formas de saber que elemento se ha seleccionado:

  • Pasando un parámetro con y recogiéndolo en el método action con la llamada:
FacesContext.getCurrentInstance().getExternalContext().
getRequestParameterMap().get("idDelParametro").

  • Accediendo al control tabla en la parte servidor y obteniendo el objeto de negocio asociado a su fila seleccionada:

FacesContext facesContext = FacesContext.getCurrentInstance();
UIViewRoot root = facesContext.getViewRoot();

UIData table = (UIData)root.findComponent(“idDelFormulario”).
findComponent(“idDeLaTabla”);

ObjetoNegocio seleccionado = (ObjetoNegocio)table.getRowData();

Por otro lado, para pasar el objeto seleccionado al bean asociado a la siguiente página podemos aplicar tres métodos. Estos trozos de código habría que añadirlos en el método que procese el action que provoque el cambio de página. Justo después de ellos devolveríamos la cadena que hace que se navegue a la siguiente vista:

  • Utilizar el mismo bean para las dos páginas y guardarlo en sesión, quedándonos una copia del objeto seleccionado dentro de un atributo del bean:
this.objetoActivo = seleccionado;

  • Guardar en la petición el objeto seleccionado para que el siguiente bean lo recupere en un getter al inicializar la página:
HttpServletRequest request = (HttpServletRequest)

facesContext.getExternalContext().getRequest();

request.setAttribute("objetoActivo", seleccionado );

  • Acceder desde el API JSF al siguiente bean y pasarle el objeto explícitamente:
FacesContext FCInstance = FacesContext.getCurrentInstance();
String theBeanName = "informeManager";
Bean bean = (Bean) FCInstance
.getELContext().getELResolver().getValue(
FCInstance.getELContext(), null, theBeanName);
bean.setObjetoActivo(seleccionado);

Es importante darse cuenta de que cuando se usa dicho método, no es necesario que el bean “siguienteBean” este en sesión, sino que JSF lo creara, si es necesario, al llamar a Util.getValueBinding() (al estilo de como lo hacen los tags JSF).

Por otro lado, si los beans están en sesión, puede ser deseable, al llamar al setter, pasar un clon del objeto seleccionado, en lugar del objeto seleccionado en si. De esta forma evitamos que cambios en la página de detalle se propaguen al listado.


  • MENSAJES DE ERROR:
<h:message for="nombre"></h:message>

despliega los errores que se produzcan para el componente que tenga el id "nombre". Los errores son de validación; en el caso de este componente, solo se valida que sea obligatorio. Si se hace submit sin haberlo completado, se desplegará el mensaje correspondiente. Si no se pone este tag, Jsf informa de igual manera el error, pero no lo muestra por pantalla, sino que se ve en la consola. Los mensajes son predeterminados por Jsf; igualmente se pueden cambiar a nuestro gusto.

1 comentario:

  1. Hola, quisiera hacerte una pregunta, espero me puedas ayudar, he estado haciendo una aplicacion con jsf 2. Tengo un archivo index.xhtml el cual contiene el siguiente codigo html y los tags de jsf, pero al momento de ejecutar la aplicacion unicamente se muestra el html mientras que lo de jsf no se muestra, como botones y tablas.
    Alguna ayuda?

    ResponderEliminar