Introduzione
Negli articoli precedenti abbiamo introdotto alcuni concetti teorici di base su JSF. Abbiamo parlato del modello a componenti ed eventi, e abbiamo introdotto il ciclo di vita di gestione delle richieste di JSF. Ora andremo a vedere un primo semplice esempio di applicazione, il classico login, che ci consentirà di capire come i concetti esaminati si traducano poi nella pratica. L'applicazione che vedremo è volutamente semplice, in quanto l'obiettivo è puntualizzare alcuni concetti e non esaminare nel dettaglio tutte le possibilità fornite a livello di codice da JSF.
Un semplice esempio
L'esempio che vediamo è un'applicazione costituita da due pagine. La prima, la login.jsp, contiene il classico form di immissione delle credenziali dell'utente, username e password. La seconda pagina, risultato.jsp, è la pagina che informa sull'esito dell'operazione di login. L'esempio è disponibile come WAR nel file allegato scaricabile dal link in alto a sinistra. Il codice della pagina JSP login.jsp è il seguente:
<%@ page contentType="text/html;charset=windows-1252"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
<title>login</title>
</head>
<body>
<f:view>
<h:form>
<table cellspacing="2" cellpadding="3" border="0" width="100%">
<tr>
<td>Username: </td>
<td>
<h:inputText value="#{utente.username}" />
</td>
</tr>
<tr>
<td>Password: </td>
<td>
<h:inputSecret value="#{utente.password}" />
</td>
</tr>
<tr>
<td>
<h:commandButton value="Login" action="#{utente.login}"/>
</td>
<td> </td>
</tr>
</table>
</h:form>
</f:view>
</body>
</html>
Gli elementi principali da notare sono:
- Le direttive taglib per importare le librerie JSF:
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
- I custom tag utilizzati:
<h:inputText>,<h:inputSecret>e<h:commandButton>che rappresentano una text-box di input di tipo text, una di tipo password ed un command button.
La seconda pagina, risultato.jsp, mostra l'esito del login:
<%@ page contentType="text/html;charset=windows-1252"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
<title>risultato</title>
</head>
<body>
<f:view>
<h:outputText value="Benvenuto: "/>
<h:outputText value="#{utente.username}"/>
</f:view>
</body>
</html>
Il Managed Bean
Il codice Java del bean UtenteBean è il seguente:
package it.mokabyte.jsf;
public class UtenteBean {
private String username;
private String password;
public UtenteBean() {
}
public String login() {
String outcome;
// Qui va inserito il richiamo alla logica per
// l'autenticazione dell'utente
if ((username != null && username.trim().equals("mokabyte")) &&
(password != null && password.trim().equals("mokabyte"))) {
outcome = "success";
} else {
outcome = "failure";
}
return outcome;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword() {
return password;
}
}
La configurazione: faces-config.xml
Il file faces-config.xml contiene la configurazione dell'applicazione JSF. Vediamo prima le regole di navigazione:
<navigation-rule>
<from-view-id>/login.jsp</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/risultato.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>failure</from-outcome>
<to-view-id>/login.jsp</to-view-id>
</navigation-case>
</navigation-rule>
Come si vede è possibile definire delle regole di navigazione tra i tag <navigation-rule></navigation-rule> in base alle quali è possibile stabilire tutti i percorsi possibili del flusso di navigazione a partire da una vista di partenza. Nel nostro caso dalla vista login.jsp è possibile passare alla vista risultato.jsp nel caso in cui l'outcome del caso di navigazione sia uguale a success, altrimenti il flusso rimanda alla pagina di login nel caso in cui l'outcome del caso di navigazione sia uguale a failure.
Poi va definito il managed bean:
<managed-bean> <managed-bean-name>utente</managed-bean-name> <managed-bean-class>it.mokabyte.jsf.UtenteBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean>
Viene associato in questo modo un nome logico "utente" a un'istanza della classe it.mokabyte.jsf.UtenteBean vista in precedenza, e questa istanza viene memorizzata in sessione. L'istanziamento e la gestione di questo bean è completamente a carico del framework. All'interno delle viste dell'applicazione è possibile quindi fare riferimento al nome logico ad esso associato per leggere e scrivere nelle proprietà del bean o per referenziare un suo metodo con la notazione vista nelle pagine JSP precedenti: value="#{utente.username}". Questo è quello che abbiamo fatto nella pagina di login con le proprietà username e password e con il metodo login.
La configurazione del servlet nel web.xml
Nel file web.xml va definita la servlet di JSF:
<servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
Va poi ovviamente definito il mapping corretto per questa servlet. Un modo per effettuare il mapping è il seguente:
<servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping>
In questo modo ogni richiesta mappata su un URL del tipo /faces/nomepagina.jsp viene gestita dal controller di JSF. Ad esempio, l'URL di richiesta della nostra pagina di login.jsp è del tipo:
http://server_name:port/appname/faces/login.jsp
Conclusioni
In questo articolo abbiamo visto un primo semplicissimo esempio di applicazione JSF. Ovviamente lo scopo non era di presentare una applicazione spettacolare ma piuttosto di introdurre alcuni elementi di base che consentano di iniziare a comprendere, da un lato, come i concetti teorici già visti si traducono nella pratica e, dall'altro, come è strutturata a livello di codice un'applicazione JSF. Ovviamente sono stati tralasciati per semplicità molti aspetti quali la validazione dei campi, la gestione dei messaggi di errore, le modalità di invocazione della business logic e molti altri che saranno presentati successivamente.
Riferimenti
- [1] David Geary, Cay Horstmann, "Core Java Server Faces", Sun Microsystems Press, 2004
- [2] Bill Dudney, Jonathan Lehr, Bill Willis, LeRoy Mattingly, "Mastering Java Server Faces", Wiley Publishing, 2004
- [3] Kito D. Mann, "Java Server Faces In Action", Manning Publications, 2005
- [4] Autori Vari, "The Java EE 5 Tutorial", Sun Microsystems, Febbraio 2007
