Introduzione
Java Server Faces è un framework per la realizzazione di applicazioni web in java. Similmente ad altri framework proprietari come Struts o Spring MVC, JSF segue il pattern architetturale Model View Controller (MVC), con la differenza che JSF è uno standard ufficiale definito nelle specifiche Java Enterprise Edition.
Generazione del progetto
Per la nostra applicazione di esempio utilizziamo java 8, Eclipse Luna (con JBoss Tools 4.2.3) e WildFly 8 come Application Server, ma è possibile utilizzare anche un Servlet Engine come Tomcat. Procediamo quindi con la creazione del progetto base utilizzando Maven. Apriamo quindi la schell e posizioniamoci nella cartella dove vogliamo creare il progetto e digitiamo:
1 2 3 4 |
mvn archetype:create -DgroupId=it.inspiredsoft.employees -DartifactId=jsf-employees -DarchetypeArtifactId=maven-archetype-webapp |
DgroupId
e DartifactId
come meglio credete. Aprite quindi il file web.xml
e cancellate il doctype
seguente:
1 2 3 |
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > |
web-app
con:
1 2 3 |
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> |
Completiamo la procedura aggiornando anche la versione della facets a 2.5 accedendo alle proprietà del progetto. Se Eclipse ve lo impedisce potete disabilitare la facet Dynamic Web Module e quindi eseguire Maven->Update Project
e Maven provvederà a abilitare la facet nella versione corretta.
Dipendenze
Aggiungiamo dell’applicazione le dipendenze per JSF 2.0 accedendo al pom.xml nella root del progetto. La dependency da aggiungere è funzione di dove sarà deployata l’applicazione.
Per un Java EE Application Server (GlassFish, JBoss AS, etc):
1 2 3 4 5 6 |
<dependency> <groupId>javax.faces</groupId> <artifactId>jsf-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> |
Per deploying to a servlet container (Tomcat, Jetty, etc):
1 2 3 4 5 6 7 8 9 10 11 12 |
<dependency> <groupId>com.sun.faces</groupId> <artifactId>jsf-api</artifactId> <version>2.0.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>com.sun.faces</groupId> <artifactId>jsf-impl</artifactId> <version>2.0.2</version> <scope>runtime</scope> </dependency> |
Si noti che nel primo caso lo scope
della dipendenza è provided
perché gli application server conformi alla specifica J2EE dispongono già delle librerie che implementano la specifica JSF. Proseguiamo aggiungendo il plugin necessario per la compilazione:
1 2 3 4 5 6 7 8 9 10 |
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> |
Configurazione
Per poter utilizzate JSP é necessario configurare servlet che gestisce le richieste provenienti dalle interfacce web costruite utilizzando JSF. Per farlo apriamo il file web.xml
ed inseriamo l’xml mostrato di seguito:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> |
Il parametro javax.faces.PROJECT_STAGE
impostato a Development
indica a JSF di di fornire messaggi di errore più accurati anche lato client, al costo di una riduzione delle performance. Viceversa impostandolo a Production
l’attenzione maggiore sarà data alle performance mentre i messaggi saranno meno accurati.
Welcome page
A questo punto inseriamo nel progetto la prima “semplice” pagina di benvenuto in JSF. Per farlo creiamo il file index.xhtml
nella cartella webapp
ed inseriamo la welcome page nel web.xml
:
1 2 3 |
<welcome-file-list> <welcome-file>index.xhtml</welcome-file> </welcome-file-list> |
Si noti che la specifica suggerisce l’utilizzo di pagine in formato XHTML con estensione .xhtml,
la servlet infatti è configurata in modo da processare pagine con tale estensione. Il contenuto del file sarà:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <title>JSF 2.0 Hello World</title> </h:head> <h:body bgcolor="white"> <h2>JSF 2.0 Hello World Example</h2> </h:body> </html> |
Managed Bean
In JSF i bean che possono essere acceduti dalle pagine JSF sono detti managed bean. Si tratta di normalissimi bean java che possono contenere proprietà con i relativi metodi get e set, ma anche logica di business. Un managed bean può essere configurato sia utilizzando un file XML (faces-config.xml obbligatorio in JSX 1.x) ma anche attraverso le annotation. Tornando al nostro esempio, creiamo il managed bean HelloBean
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import java.io.Serializable; @ManagedBean @SessionScoped public class HelloBean implements Serializable { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } |
Modifichiamo quindi la pagina index.xhtml
, aggiungendo una form con un input text ed un pulsante di sottomissione:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <title>JSF 2.0 Hello World</title> </h:head> <h:body bgcolor="white"> <h2>JSF 2.0 Hello World Example</h2> <h:form> <h:inputText value="#{helloBean.name}"></h:inputText> <h:commandButton value="Welcome Me" action="welcome"></h:commandButton> </h:form> </h:body> </html> |
L’input text è collegato alla proprietà name
del bean HelloBean
, mentre il pulsante ha nell’action
la redirezione verso la pagina welcome.xhtml
così definita:
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <title>JSF 2.0 Hello World</title> </h:head> <h:body bgcolor="white"> <h2>JSF 2.0 Hello World Example</h2> <h2>Welcome #{helloBean.name}</h2> </h:body> </html> |
Si noti che in JSF 1.x era necessario definire delle regole di navigazione nel file faces-config.xhtml
per indicare quale pagina visualizzare a seguito di una action. Con JSF 2.0 è possibile indicare la pagina direttamente nella proprietà action
di un pulsante.
Deploy
Nel mio caso ho deciso di utilizzare il plug-in di Eclipse per gestire il deploy su WildFly. Semplicemente definite un Runtime Server WildFly 8.x con Java 8 ed inseritelo nella vista Servers
. Quindi selezionate Add and Remove
facendo tasto destro sul nome del server. Avviate ed aprite il browser alla pagina http://localhost:8080/jsf-employees/. Se tutto va bene vedrete:
Utilizzando il plug-in può accadere che vi compaia il messaggio “Forbidden“. In questo caso aprite le proprietà del progetto ed ispezionate la configurazione “Deployment Assembly“. In particolare verificate che la cartella /src/main/webapp
sia mappata su /
.
Download codice sorgente
Il progetto completo è disponibile qui jsf-employees.