Navegación de Páginas en JSF
En esta segunda entrega del tutorial de JSF (que espero no seguir postergando), podría hablar de configuración e inicio de un proyecto con JSF, pero dado que el tema es fácil de encontrar y además me resulta bastante aburrido, comenzaré directamente desde lo básico de navegación, dado por sentado que tienen configurado un entorno. Pueden bajarse una estructura de proyecto en blanco desde acá. Comencemos!
Flujo de control de navegación simplificado
- Se muestra un form
- El form se hace submit a sí mismo
- Se instancia el bean
- Se llama al método de la acción
- El método de la acción retorna una condición
- Se muestra una pantalla de resultado
Para poder desarrollar esta parte del tutorial, vamos a necesitar:
- Mapeos en el archivo faces-config.xml
- Un form
- Un managed bean
Vayamos paso por paso, primero:
Los mapeos
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ... <faces-config> <managed-bean> <managed-bean-name>loginBean</managed-bean-name> <managed-bean-class>com.ejemplo.login.LoginBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <navigation-rule> <display-name>Login page</display-name> <from-view-id>/public/login/login.jsp</from-view-id> <navigation-case> <from-outcome>success</from-outcome> <to-view-id>/public/login/loggedin.jsp</to-view-id> <redirect/> </navigation-case> <navigation-case> <from-outcome>failure</from-outcome> <to-view-id>/public/login/loginerror.jsp</to-view-id> <redirect/> </navigation-case> </navigation-rule> ... </faces-config> |
Con este archivo de configuración hemos hecho dos cosas:
Declarar el managed bean como de sesión, para que mantenga su estado entre llamadas, y además Indicar reglas de navegación para que al recibir un String desde el login.jsp, jsf pueda determinar que camino tomar, en nuestro caso:
- “success”: redirecciona a loggedin.jsp
- “failure”: redirecciona a loginerror.jsp
Ya veremos luego como hacer que lleguen estos strings a JSF para que pueda decidir, es más facil de lo que pueden llegar a imaginarse, pero por ahora pasemos a…
El form
El form es la parte del sistema mediante la cual el usuario se comunicará con el managed bean, y el código para crearlo sería más o menos como el que sigue:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <h:form id="loginForm"> <h:outputLabel value="Usuario" /> <h:inputText value="#{loginBean.userName}" id="usernameInput" size="20" tabindex="1"> </h:inputText> <h:outputLabel value="Contraseña" /> <h:inputSecret value="#{loginBean.password}" id="loginPasswordInput" size="20" tabindex="2"> </h:inputSecret> <h:commandButton value="Entrar" action="#{loginBean.logged}" id="login" /> </h:form> |
Vamos a destriparlo un poco para ver si se entiende mejor. Descartemos en principio las partes menos importantes, los atributos size y tabindex, y los tag no son realmente necesarios para el ejemplo, pero los coloqué igual para que quedara un poco mejor presentado el form. Considerando que los h:outputLabel sólo muestran las etiquetas de las cajas de texto, sólo nos quedan los inputs y el button, que son lo que importa.
Veamos los inputs, de a uno:
1 2 3 | <h:inputText value="#{loginBean.userName}" id="usernameInput" size="20" tabindex="1"> </h:inputText> |
Este tag es sencillo, genera un Input HTML del tipo “text”, y se conecta al atributo userName de nuestro managed bean (el cual aún no hemos codificado) mediante el value=”#{loginBean.userName}”, utilizando el nombre que declaramos para el bean en el faces-config.xml (loginBean, con minúscula al comienzo). Ahora ya empezamos a ver cosas “raras” como #{loginBean.userName}, y quizás tenga que explicar un poco más de que se trata. Si bien podría estar largo rato explayandome sobre este tema, me parece más correcto resumirlo sólo para saber para que lo utilizaremos. Cuando necesitemos acceder a atributos o métodos de los managed beans, usaremos algo llamado Expression Language (EL), implementado inicialmente por JSP en la forma ${bean.atributo} y luego modificado para JSF, con ciertas mejoras y un ligero cambio en su sintaxis: #{bean.atributo}; sí, sólo cambia el “$” por el “#”. Como podrán darse cuenta, este método de acceso a los atributos y métodos del managed bean puede simplificarnos mucho la vida
.
Ahora vamos con el de la contraseña:
1 2 3 | <h:inputSecret value="#{loginBean.password}" id="loginPasswordInput" size="20" tabindex="2"> </h:inputSecret> |
¿Qué tiene de diferente este con el anterior? Bien, sólo que en vez de renderizarse como un Input tipo “text” HTML, lo hace como uno del tipo “password” así se enmascara el texto escrito en él. Simple, ¿No?
Ahora pasamos al button, que también es muy facil de entender.
1 | <h:commandButton value="Entrar" action="#{loginBean.logged}" id="login" /> |
En este caso, value es el texto que se muestra en el botón, mientras que el atributo action=”#{loginBean.logged}” le está indicando al form que llame al método logged del managed bean loginBean. Ahora, dependiendo del String que devuelva este bean, jsf elegirá uno u otro camino, como configuramos antes en el faces-config. Por lo tanto, es hora de que pasemos a ver
El managed bean
El managed bean es el que se encarga de manejar la lógica de nuestra página jsp, además de ser también quien contiene los atributos (cadenas, valores, listas, etc) que serán accedidos desde la pantalla tanto para mostrarlos al usuario, como para almacenarlos en memoria. Codifiquemos ahora un managed bean muy simple para nuestro ejemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class LoginBean { private String userName; private String password; public String logged() { if (checkPassword(userName, password)) return "success"; else return "failure"; } public setUserName(String userName) { this.userName = userName; } public String getUserName() { return userName; } public setPassword(String password) { this.password = password; } public String getPassword() { return password; } } |
En este managed bean simplemente tenemos un método llamado logged, además de los atributos userName y password con sus respectivos get/set, de modo que podamos acceder a ellos desde la interfaz. El método del ejemplo es bastante sencillo, sólo “chequea” el nombre de usuario y la contraseña (usando el método checkPassword, el cual no es necesario implementar para este tutorial), devolviendo luego un String que será el que le indique a JSF que camino tomar según lo especificado por nosotros en el faces-config.xml. Por lo tanto si el nombre de usuario es válido se redigirá a la página logged.jsp, mientras que en caso de no serlo será redirigido a loginerror.jsp.
Creo que esto será todo por ahora. La idea de este tutorial es ser lo más simple y conciso posible, pero cualquier duda que tengan o si necesitan que sea más extenso en ciertos temas, no duden en decirlo en los comentarios. Ya veremos que nos depara la próxima entrega de este tutorial (esperemos que no se demore tanto como esta).
This entry was posted on Tuesday, July 8th, 2008 at 2:01 pm and is filed under Desarrollo Web, JSF, Tutoriales. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.




The Doctor September 15th, 2009 at 10:58 pm
Hola… La mejor forma de que el usuario sólo acceda a ciertas páginas (por ej “loggedin.jsp”) es hacer un filtro[1], con lo cual te puede quedar algo parecido a esto:
En ese código se fija si la sesión es nula o el usuario no logueado está intentando entrar a una página que no sea la principal, y lo redirige.
La mejor forma es tener las páginas que necesitan login en una carpeta aparte, y filtrar por esa carpeta. Sé que tengo un ejemplo de eso, pero aún no encuentro el código. Si lo encuentro y aún te interesa, lo pego.
El código de arriba está sacado del resultado de este foro: http://www.coderanch.com/t/452077/JSF/java/JSF-Filter-prevent-direct-access