Sei sulla pagina 1di 9

JJ n.

1 novembre-dicembre 2006

Primi passi con JavaServer Faces


` di Michele Sciabarra
Le JavaServer Faces sono da molti considerate il tassello mancante per rendere lo ` ` ` sviluppo di applicazioni Web piu semplice. Nella realta e uno strumento molto potente per realizzare un certo tipo di applicazioni, ovvero quelle dotate di numerose form per il data-entry. Come tutti gli strumenti di questo genere, sono abbastanza complesse e richiedono un po di tempo e impegno per essere padroneggiate. Prima di entrare nei dettagli della tecnologia con il prossimo articolo, e descrivere il suo prossimo futuro, mostriamo prima di tutto con un esempio pratico come funzionano.

` Michele Sciabarra ` Michele Sciabarra si occupa di Java n da quando, nel 1993, ` scarico il sorgente di HotJava e per compi` larlo saturo il disco della Workstation Sun che amministrava. Da allora ha lavorato in Java passando dalle applet per Netscape 2 no alle applicazioni bancarie di classe enterprise. Dopo aver scritto di Java e averlo insegnato per ` dieci anni, e direttore esecutivo di Java Journal. Quando non cerca di imparare le ultime API o disquisisce ` della superioritaa del modello Open Source, si diletta a programmare cellulari Symbian in C++ e amministrare sistemi Linux.

pubblicato su WWW.INFOMEDIA.IT stampa digitale da Lulu Enterprises Inc. stores.lulu.com/infomedia


Infomedia
` Infomedia e limpresa editoriale che da quasi venti anni ha raccolto la voce dei programmatori, dei sistemisti, dei professionisti, degli studenti, dei ricercatori e dei professori dinformatica italiani. Sono pi` di 800 gli autori che hanno realizzato per le teu state Computer Programming, Dev, Login, Visual Basic Journal e Java Journal, molte migliaia di articoli tecnici, presentazioni di prodotti, tecnologie, protocolli, strumenti di lavoro, tecniche di sviluppo e semplici trucchi e stratagemmi. Oltre 6 milioni di copie distribuite, trentamila pagine stampate, fanno di questa impresa la pi` grande ed u inuente realt` delleditoria specializzata nel campo della a programmazione e della sistemistica. In tutti questi anni le riviste Infomedia hanno vissuto della passione di quanti vedono nella programmazione non solo la propria professione ma unattivit` vitale e un vero a divertimento. ` Nel 2009, Infomedia e cambiata radicalmente adottando ` un nuovo modello aziendale ed editoriale e si e organizzata attorno ad una idea di Impresa Sociale di Comunit` , a partecipata da programmatori e sistemisti, separando le attivit` di gestione dellinformazione gestite da un board a comunitario professionale e quelle di produzione gesti` te da una impresa strumentale. Questo assetto e in linea con le migliori esperienze internazionali e rende Infomedia ancora di pi` parte della Comunit` nazionale degli u a sviluppatori di software. ` Infomedia e media-partner di manifestazioni ed eventi in ambito informatico, collabora con molti dei pi` imporu tanti editori informatici italiani come partner editoriale e fornitore di servizi di localizzazione in italiano di testi in lingua inglese.

Limpaginazione automatica di questa rivista e realizzata al ` 100% con strumenti Open Source usando OpenOffice, Emacs, BHL, LaTeX, Gimp, Inkscape e i linguaggi Lisp, Python e BASH

For copyright information about the contents of Java Journal, please see the section Copyright at the end of each article if exists, otherwise ask authors. Infomedia contents is 2006 Infomedia and released as Creative Commons 2.5 BY-NC-ND. Turing Club content is 2006 Turing Club released as Creative Commons 2.5 BY-ND. Le informazioni di copyright sul contenuto di Java Journal sono riportate nella sezione Copyright alla ne di ciascun articolo o vanno richieste direttamente agli autori. Il contenuto Infomedia e 2006 Infomedia e rila` sciato con Licenza Creative Commons 2.5 BY-NC-ND. Il contenuto Turing Club e 2006 Turing Club e rilasciato ` con Licenza Creative Commons 2.5 BY-ND. Si applicano tutte le norme di tutela dei marchi e dei segni distintivi. ` E in ogni caso ammessa la riproduzione parziale o totale dei testi e delle immagini per scopo didattico purch e vengano integralmente citati gli autori e la completa identicazione della testata. Manoscritti e foto originali, anche se non pubblicati, non si restituiscono. Contenuto pubblicitario inferiore al 45%. La biograa dellautore riportata nellarticolo e sul sito www.infomedia.it e di norma quella disponibi` le nella stampa dellarticolo o aggiornata a cura dellautore stesso. Per aggiornarla scrivere a info@infomedia.it o farlo in autonomia allindirizzo http://mags.programmers.net/moduli/biograa

speciale JavaServer Faces

JAVA Journal

Primi passi con JavaServer Faces


Le JavaServer Faces sono da molti considerate il tassello mancante per rendere lo sviluppo di applicazioni Web pi semplice. Nella realt uno strumento molto potente per realizzare un certo tipo di applicazioni, ovvero quelle dotate di numerose form per il data-entry. Come tutti gli strumenti di questo genere, sono abbastanza complesse e richiedono un po di tempo e impegno per essere padroneggiate. Prima di entrare nei dettagli della tecnologia con il prossimo articolo, e descrivere il suo prossimo futuro, mostriamo prima di tutto con un esempio pratico come funzionano.
>> di Michele Sciabarr (michele.sciabarra@javajournal.it)

e JavaServer Faces sono state progettate per ridurre il codice da scrivere quando una applicazione Web ha numerose form; quasi sempre si tratta di una interfaccia a dati memorizzati su un database relazionale. In una applicazione Web in Java tradizionale, ci sono delle JavaServer Pages o delle servlet che producono esplicitamente tutto lhtml necessario per visualizzare le form. Per gestire le form il programmatore Web finora doveva fare da solo. Una applicazione Web infatti richiede una serie di automatismi che con le sole JSP non possiede: necessario riempire le form con dei dati, mantenere uno stato, raccogliere e decodificare i dati, spesso codificarli o decodificarli, e infine salvarli in un database. Per quanto riguarda la gestione del database, questo compito di librerie ORM (Object Relational Mapping), e non verr considerato nel presente articolo. Le JavaServer Faces hanno lobiettivo principale di aumentare lautomatismo per riempire le form con i dati, recuperarli quando lutente li inserisce, e in generale gestire linterazione con lutente. Vedremo come fare costruendo un esempio pratico passo passo. Si tratter di un esempio molto semplice, ridotto allosso, che visualizza un elenco dati e permette di modificarlo. La memorizzazione dei dati verr gestita con uno stub, una classe minimale (da estendere eventualmente) perch altrimenti andremmo fuori dallo scopo dellesempio. Personaggi e Interpreti Prima di entrare nei dettagli, elenchiamo i componenti che compongono una applicazione realizzata con JavaServer Faces. In particolare tratteremo delle JSF versione 1.1. Innanzitutto avremo alcune pagine JSF. Le pagine

JSF sono in realt delle pagine JSP che contengono dei tag provenienti dalla libreria Faces. Tuttavia, una pagina in JSF deve essere chiamata con lestensione.faces (non .jsp) o con il prefisso /faces/; su disco per vengono memorizzate con la classica estensione .jsp. Dove linghippo? Semplice: quando installiamo le JSF, dobbiamo configurare nellapplicazione Web una servlet, la faces servlet che interpreta le pagine JSF. Questa servlet prepara lambiente perch una JSF possa essere eseguita. In effetti un sistema un po strano, non ovvio; purtroppo questo trucco necessario perch si possa mantenere la compatibilit con molti application server esistenti. Oltre alle pagine JSF avremo delle classi, che sono necessarie per usare le JSF. A differenza delle JSP infatti, le JSF prevedono che molte operazioni delle JSF, vengano svolte in delle classi apposite, dette Backing Bean.

Le pagine JSF sono


pagine JSP che contengono tag provenienti dalla libreria Faces

Da questi Backing Bean le pagine JSF leggono i dati, li scrivono dopo averli utilizzati, e causano lesecuzione di azioni a seguito di eventi, che avvengono quando lutente fa delle operazioni sulle maschere

10

n.1 - novembre/dicembre 2006

JAVA Journal
prodotte. Per collegare Backing Bean a pagine JSF, si utilizza un file di configurazione, chiamato solitamente faces-config.xml. Questo file innanzitutto contiene la definizione di tutti i backing bean. Un altro elemento importante delle JSF che la navigazione (il passaggio da una pagina allaltra) viene definita in astratto. Ogni volta che serve una navigazione, un backing bean o una jsf non dice esplicitamente dove vogliono andare, codificando lurl della destinazione: invece viene data una risposta generica, codificata con una stringa. La navigazione effettiva viene dichiarata nel faces-config.xml Installazione di JSF Prima di andare avanti, vediamo come installare la versione RI 1.1 delle JSF (la Reference Implementation fornita da Sun) nella vostra applicazione Web. Notare che ne esistono altre come le MyFaces, ma la RI sembra al momento essere la pi usata. Si presume in questo articolo che abbiate familiarit con le configurazioni delle WebApp, e in particolare sappiate cosa e a cosa serve la directory WEB-INF/lib e il file web.xml. Questo esempio fa riferimento allinstallazione delle JSF versione 1.1 nellapplication server Tomcat, in particolare alla sua versione 5.5. Se usate un diverso application server pu essere
commons-logging.jar commons-digester.jar commons-beanutils.jar commons-collections.jar jstl.jar standard.jar

JavaServer Faces speciale

Copiato tutto nella WEB-INF/lib occorre configurare, aggiungendo nel web.xml quanto mostrato nel Listato 1.

FIGURA 1

I componenti della Agenda

<context-param> <param-name>javax.faces.CONFIG_FILES </param-name> <param-value>/WEB-INF/faces-config.xml </param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class> javax.faces.webapp.FacesServlet </servlet-class> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.faces</url-pattern> </servlet-mapping>

La configurazione installa una servlet, la Faces Servlet, che viene richiamata per interpretare le JSP che contengono tag di tipo Faces. Ancora una volta ricordo il trucco: se avete un file che si chiama pagina.jsp (e dovete avere una pagina di questo tipo), la dovete richiamare con il nome pagina.faces. Se la chiamate con lestensione jsp, otterrete un errore, perch non vengono eseguite le inizializzazioni necessarie per le JSF.

Lesempio mostrato
il prototipo di ogni applicazione basata su JSF

LISTATO 1 Le configurazioni nel web.xml delle JSF


necessario variare le operazioni opportunamente. Per installare JSF occorre scaricare il pacchetto versione 1.1 da java.sun.com/j2ee/javaserverfaces. In prima approssimazione basta copiare due jar nella directory WEB-INF/lib, ovvero la jsf-api.jar e jsf-impl.jar. Come costume, il primo jar rappresenta la API come definita dalla specifica, mentre il secondo ne limplementazione. Questi due JAR per non sono sufficienti in quanto limplementazione di Sun usa una serie di librerie esterne, peraltro abbastanza note e usate: sono alcuni dei commons del progetto Apache. Infine servono anche le le librerie della Java Standard Template Library. Ecco lelenco di quelle necessarie:

Lapplicazione Agenda Come esempio scriviamo una applicazione dimostrativa, una semplice agenda che permette di visualizzare un elenco di nomi, aggiungerli o toglierli, ed editare un dettaglio. Pur nella sua assoluta semplicit questa miniapplicazione il prototipo di qualunque applicazione significativa per cui si usano le JSF. Il suo studio fornisce un buon trampolino di lancio per avventurarsi in applicazioni pi complesse. In Figura 1 ho schematizzato con

n.1 - novembre/dicembre 2006

11

speciale JavaServer Faces

JAVA Journal
AgendaForm.jsp in risposta a una richiesta form, e viceversa in risposta a una richiesta list.

<managed-bean> <managed-bean-name>agenda </managed-bean-name> <managed-bean-class>agenda.Agenda Backing</managed-bean-class> <managed-bean-scope>session </managed-bean-scope> </managed-bean> <navigation-rule> <from-view-id>/agenda/AgendaList.jsp </from-view-id> <navigation-case> <from-outcome>form</from-outcome> <to-view-id>/agenda/AgendaForm.jsp </to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/agenda/AgendaForm.jsp </from-view-id> <navigation-case> <from-outcome>list</from-outcome> <to-view-id>/agenda/AgendaList.jsp </to-view-id> </navigation-case> </navigation-rule>

I componenti di una
applicazione JSF vengono configurati nel file faces-config.xml

Il database Stiamo costruendo una applicazione che gestisce nei fatti una tabella di dati. Per semplicit, non ci preoccuperemo di leggere e scrivere effettivamente i dati sul database, ma ci limiteremo a mantenerli in memoria, utilizzando consuete strutture dati come liste e mappe. Comunque, sar possibile salvare i dati effettivamente su database semplicemente implementando i metodi appositi di lettura e scrittura, che nel nostro caso si limitano a tenere tutto in memoria. Per mantenere un record, utilizziamo un javabean, ovvero una classe Java i cui campi sono accessibili con getter e setter; si tratta di Pojo (Plain Old Java Object) nellaccezione corrente. Questo oggetto ha i campi nome, email e telefono, con relativi getter e setter. Per predisporre il file nella scrittura sul database, abbiamo anche un campo id di tipo Long, campo che viene generato automaticamente (usando il noto metodo del timestamp per creare un identificatore univoco). Un database di bean viene mantenuto in memoria e gestito tramite metodi statici della classe agenda. Sarebbe stato forse opportuno separare i metodi statici dalla classe Agenda, ma per semplicit ho messo tutto nella stessa classe. Per creare un nuovo bean useremo Agenda a = new

LISTATO 2 La configurazione del faces-config.xml un diagramma, i principali componenti di questa applicazione, e la sua navigazione. Il diagramma non usa nessuna notazione particolare: semplicemente ho indicato con licona dei documenti, le pagine jsf, mentre con un rombo il backing bean. I dati vengono letti e scritti in un database, che in realt un database vero non , ma solo una collezione di bean in memoria. Il meccanismo comunque si estende in maniera naturale verso la memorizzazione in un vero database, utilizzando un qualsiasi sistema ORM (per esempio Hibernate). In figura abbiamo anche evidenziato lo schema di navigazione, che elementare: dalla lista si passa alla form e viceversa. Come abbiamo detto, i componenti di una applicazione JSF vengono esplicitamente configurati nel facesconfig.xml. Di solito il file di configurazione si scrive alla fine; siccome sappiamo gi quali file avremo nella nostra applicazione, lo scriviamo per primo e ci togliamo dimpiccio. Nel file di configurazione ci sono numerose possibilit, ma ai fini del nostro esempio ci interessano solo due cose: definire i backing bean, e configurare la navigazione. La configurazione mostrata nel Listato 2. Il Backing Bean uno solo, di classe agenda.AgendaBacking, che verr richiamato con il nome agenda. La navigazione invece va dal file /agenda/AgendaList.jsp al file /agenda/

FIGURA 2

Visualizzazione della lista dei record

12

n.1 - novembre/dicembre 2006

JAVA Journal
package agenda; // import omissis public class Agenda { // trucco per generare facilmente // id univoci static long counter= System.currentTimeMillis(); // campi con getter e setter Long id = new Long(counter++); public Long getId() { return id; } public void setId(Long id) { this.id = id; } String nome; public String getNome() { return nome; } public void setNome(String nome) {this.nome = nome;} String email; public String getEmail() { return email; } public void setEmail(String email) {this.email = email; } String phone; public String getPhone() { return phone;} public void setPhone(String phone) {this.phone= phone; } // costruttori public Agenda() { this(,,); } public Agenda(String nome, String email,String phone) { super(); this.email = email; this.nome = nome; this.phone = phone; }

JavaServer Faces speciale

// gestione del database // in memoria private static List<Agenda> list = new LinkedList<Agenda>(); private static Map<Long, Agenda> map = new HashMap<Long, Agenda>(); // ritorna una lista dei bean public static List<Agenda> getList(){ return list; } // memorizza il bean public static void store(Agenda bean) { if(map.get(bean.getId())==null) list.add(bean); map.put(bean.getId(), bean); } // recupera il bean public static Agenda load(Long id) { return map.get(id); } // elimina il bean public static void remove(Agenda bean) { map.remove(bean.getId()); list.remove(bean); } // inizializzazione (una tantum) // del database static { store(new Agenda(Michele, msciab@ep,347)); store(new Agenda(Mirella, mirella@ep, 328)); store(new Agenda(Laura, laura@ep,736)); store(new Agenda(Massimo, max@ep,922)); } }

LISTATO 3 Il database dellagenda Agenda(nome, email, telefono). Per salvarlo useremo Agenda.store(a), mentre per recuperarlo (assumendo di avere gi lid) baster un Agenda.load(id). Infine, per eliminarlo possiamo utilizzare Agenda.delete(a). Il codice del database segue in Listato 3. La lista e la form La nostra applicazione composta essenzialmente di due maschere: una maschera principale che elenca tutti i record, e una seconda maschera di dettaglio, che permette di modificare il singolo record. Entrambe fanno riferimento a un unico backing bean, agenda. Iniziamo a vedere il codice della lista, in Listato 4: Nel Listato 4 possiamo vedere come si fa a ottenere un elenco di record del database, come visualizzato nella Figura 2. Si pu notare che JSF usa dei tag, con prefisso f: oppure h:, descritti in dettaglio nellarticolo successivo.

n.1 - novembre/dicembre 2006

13

speciale JavaServer Faces

JAVA Journal
(si veda larticolo sulle novit delle JSF 1.2 al riguardo).

<%@ taglib uri=http://java.sun.com/jsf/html prefix=h%> <%@ taglib uri=http://java.sun.com/jsf/core prefix=f%> <f:view> <h:form> <h:dataTable var=data border=1 binding=#{agenda.table} value=#{agenda.list}> <h:column> <f:facet name=header> <h:outputText value=Azione /> </f:facet> <h:commandButton actionListener=#{agenda.edit} value=Modifica action=form/> </h:column> <h:column> <f:facet name=header> <h:outputText value=Nome /> </f:facet> <h:outputText value=#{data.nome} /> </h:column> <h:column> <f:facet name=header> <h:outputText value=Email /> </f:facet> <h:outputText value=#{data.email} /> </h:column> <h:column> <f:facet name=header> <h:outputText value=Telefono /> </f:facet> <h:outputText value=#{data.phone} /> </h:column> <h:column> <f:facet name=header> <h:outputText value=Azione /> </f:facet> <h:commandButton actionListener=#{agenda.delete} value=Elimina action=list/> </h:column> </h:dataTable> <h:commandButton actionListener=#{agenda.create} value=Nuovo action=form/> </h:form> </f:view>

LISTATO 4 La lista dei record dellagenda Questi tag definiscono linterfaccia utente in maniera astratta. Questa infatti una delle principali difficolt nellimparare le JSF: i tag delle JSF sono completamente diversi da quelli dellHTML. Infatti una pagina JSF genera un output HTML utilizzando un render kit, ma possibile sostituirlo con un render kit di tipo diverso per produrre output come WML (per il Wap) o XUL (per applicazioni GUI basate su Firefox) o usare tecniche Ajax

Notiamo innanzitutto la h:datatable. Questo tag itera i contenuti di una lista. I valori da rappresentare vengono forniti dal backing bean, che ne fornisce la lista. Il backing bean viene richiamato con lespressione #{agenda.list}. Il file di configurazione faces-config lo definisce, e questo bean viene creato e viene posto in sessione. A questo punto loutput da visualizzare viene generato dal metodo getList() del backing bean. Notare che, come spesso succede, una propriet del backing bean viene chiamata senza usare il prefisso get, ma nel codice occorre scrivere il metodo getList. Viene prodotta cos una lista di bean, che sono di classe Agenda. Ogni bean viene posto nella variabile data e visualizzato. Unaltra caratteristica della datatable che il contenuto viene prodotto per colonna, mentre ricordiamo che in html una tabella viene definita per riga. Non c quindi una corrispondenza diretta tra una datatable JSF e una table HTML.In ogni colonna viene visualizzata la riga corrente usando le outputText che usano #{data.nome},#{ data.email},#{data.phone} per accedere alle propriet del bean (che si aspetta di tipo Agenda). Una altra osservazione il binding della datatable: le JSF costruiscono per ogni tag JSF un oggetto; nel caso della datatable viene creato un oggetto UIData; utilizzando il binding, questo oggetto viene memorizzato direttamente nel backing bean: in questo modo si possono ispezionare e ottenere informazioni come per esempio la riga corrente. Questo uso comunque abbastanza avanzato, ma una volta compreso pu essere molto potente. Vedremo come viene sfruttato esaminando il dettaglio del backing bean nel prossimo paragrafo. Infine, i comandi. Notiamo che quando si clicca un bottone viene invocato un metodo del bean specificato con actionListener. Abbiamo #{agenda.create} per creare un nuovo bean, #{agenda.delete} per cancellarlo e #{agenda.edit} per la modifica. Attenzione che in questo caso si tratta proprio dei metodi edit, create e delete, non di una propriet (quindi un metodo con il prefisso get). Tuttavia i metodi specificati come actionListener hanno anche essi degli obblighi: devono essere di tipo void e prendere un parametro di tipo ActionEvent. assolutamente essenziale ren-

14

n.1 - novembre/dicembre 2006

JAVA Journal
dersi conto che le JSF hanno un ciclo di vita sottostante, e che quindi le varie propriet ed eventi vengono usate in momenti diversi. Le propriet vengono lette prima della visualizzazione della pagina. Le azioni vengono gestite dopo che lutente ha premuto un bottone. Proseguiamo lanalisi dellesempio vedendo il dettaglio della form mostrata nel Listato 5, e il cui snapshot pu essere osservato in Figura 3. Anche in questo caso vengono usati tag astratti: la form

JavaServer Faces speciale

Il ciclo di vita delle


JSF si basa su propriet e eventi
FIGURA 3 la lista degli elementi, ma una volta selezionato un elemento permette di accedere alle singole propriet. Esaminando il dettaglio del backing bean vedremo che abbiamo creato dei metodi proxy: in pratica ogni volta che si chiama il getNome del backing bean (di classe AgendaBacking), questo chiamer il getNome della classe Agenda. In questa pagina abbiamo non solo outputText ma anche e soprattutto inputText, che permettono non solo di leggere ma anche di scrivere. Quindi questa pagina visualizza innanzitutto il record selezionato, chiamando i metodi getNome, eccetera. Quando lutente ha compilato il modulo e clicca su un bottone, il valore immesso viene riportato nel backing bean chiamando i metodi setNome, setEmail setPhone.

usa il panelGrid che permette di disporre i componenti contenuti in una tabella, senza doversi preoccupare della suddivisione in righe e colonne. Se dichiaro un panelgrid con tre colonne, viene creata una tabella con tre colonne; la prima riga conterr i primi tre elementi, la seconda riga conterr il quarto, il quinto e il sesto, e cos via. Semplice e pratico. Il nostro backing bean multifunzionale: non solo fornisce

<%@ taglib uri=http://java.sun.com/jsf/html prefix=h%> <%@ taglib uri=http://java.sun.com/jsf/core prefix=f%> <f:view> <h:form> <h:panelGrid columns=3> <h:outputLabel value=Nome: for=nome /> <h:inputText id=nome value=#{agenda.nome} /> <h:message for=nome /> <h:outputLabel value=Email: for=email /> <h:inputText id=email value=#{agenda.email} /> <h:message for=email /> <h:outputLabel value=Phone: for=phone /> <h:inputText id=phone value=#{agenda.phone} /> <h:message for=phone /> </h:panelGrid> <h:commandButton value=Salva actionListener=#{agenda.save} action=list/> </h:form> </f:view> LISTATO 5 Il dettaglio dellagenda

Il backing bean venuto il momento di chiudere il cerchio, riportando il codice del backing bean mostrato nel Listato 6. Potrebbe sembrare strano che il codice sia cos semplice, per proprio cos. Tutti i metodi sono di una sola riga, e molti metodi possono essere scritti in maniera automatica sfruttando gli automatismi forniti dagli IDE: per esempio per scrivere i getter/setter o i proxy. Per capire come funziona il tutto, vediamo cosa succede nei dettagli, avendo il codice sottocchio e tenendo presente quanto abbiamo visto nei paragrafi precedenti. Innanzitutto lutente chiama la pagina AgendaList.jsp che abbiamo visto nel Listato 3. Per visualizzare lelenco dei metodi la JSF chiama AgendaBacking.getList(). Il backing bean produce la lista dei bean prendendoli dal database, con il metodo statico Agenda.getList(). I vari bean vengono posti nella variabile data e i dati correnti vengono visualizzati. I vari #{data.name} chiamano il metodo getName della classe Agenda. La datatable accede direttamente ai bean che contengono i dati. A questo punto un utente decide di modificare un bean, e preme il bottone Modifica. La form vie-

n.1 - novembre/dicembre 2006

15

speciale JavaServer Faces

JAVA Journal
Dopo aver premuto il bottone di modifica, viene eseguito il metodo invocato dallactionListener, che imposta il bean corrente a quello selezionato, e poi si naviga alla form. Notare che nel command button specificato form mentre nel faces-config.xml specificato che da AgendaList.jsp si deve andare, su questa stringa di risposta, ad AgendaForm.jsp. Siamo quindi arrivati alla form; notare per che prima di arrivarci, si cambiato il bean corrente: in questo modo la form pu leggere e poi scrivere direttamente nel bean dati, passando per il backing bean che fa da intermediario. Quando lutente ha modificato i dati e preme salva, si esegue lo stesso meccanismo: prima viene salvato il bean nel database, poi si ritorna alla lista dei bean. Il percorso della creazione di un nuovo bean analogo, solo che il metodo create non seleziona il bean corrente ma ne crea uno nuovo. Infine la delete elimina direttamente il bean corrente senza andare alla form.

package agenda; // import omissis public class AgendaBacking { // gestione lista public List getList() { return Agenda.getList(); } private UIData table; public UIData getTable() { return table; } public void setTable(UIData table) { this.table = table; } public void edit(ActionEvent ae) { bean = (Agenda)table.getRowData(); } public void create(ActionEvent ae) { bean = new Agenda(); } public void delete(ActionEvent ae) { Agenda.remove((Agenda)table.getRowData()); } // gestione form Agenda bean; public AgendaBacking() { bean = new Agenda(); } public String getEmail() { return bean.getEmail(); } public Long getId() { return bean.getId(); } public String getNome() { return bean.getNome(); } public void setEmail(String email) { bean.setEmail(email); } public void setId(Long id) { bean.setId(id); } public void setNome(String nome) { bean.setNome(nome); } public void setPhone(String phone) { bean.setPhone(phone); } public String getPhone() { return bean.getPhone(); } public void save(ActionEvent ae) { Agenda.store(bean); } } LISTATO 6 Il dettaglio dellagenda ne inviata al server, e viene chiamato il metodo edit del backing bean. A questo punto si sfrutta il binding: la datatable sa quale la riga corrente e la fornisce a richiesta con il metodo table.getRowData(). Quindi il bean corrente viene impostato come campo del backing bean. Notare che mentre il backing bean uno solo, il bean dei dati pu variare. Il trucco usare dei metodi proxy: notare come sono scritti i getNome, getEmail, getPhone: in questo modo si varia il bean corrente e si lascia sempre lo stesso backing bean. Note Biografiche

Conclusioni Con questo esempio, serrato ma sufficientemente dettagliato, abbiamo esplorato abbastanza a fondo come funzionano le JSF: apprendendo bene i concetti qui esposti possibile cominciare a lavorare proficuamente. Le JSF comunque sono molto potenti e ricche di funzionalit: i tag sono ben pi numerosi di quelli qui esposti, e la logica sottostante (soprattutto i misteri del ciclo di vita) possono richiedere un po di tempo per essere approfonditi. I vantaggi nelluso della tecnologia comunque compensano di gran lunga il tempo investito nellapprendimento.

Michele Sciabarr si occupa di Java fin da quando, nel 93, scaric il sorgente di HotJava e per compilarlo satur il disco della Workstation Sun che amministrava. Da allora ha lavorato in Java passando dalle applet per Netscape 2 fino alle applicazioni bancarie di classe enterprise. Dopo aver scritto di Java e averlo insegnato per dieci anni, direttore esecutivo di Java Journal. Quando non cerca di imparare le ultime API o disquisisce della superiorit del modello Open Source, si diletta a programmare cellulari Symbian in C++ e amministrare sistemi Linux.

16

n.1 - novembre/dicembre 2006