In questo articolo descriviamo il ciclo di vita dell‘elaborazione di una richiesta: uno degli aspetti fondamentali da capire per poter affrontare in maniera consapevole lo sviluppo di una applicazione con Java Server Faces.
Introduzione
Abbiamo visto nel precedente articolo quali siano gli elementi caratterizzanti di JSF e sono state esposte le caratteristiche architetturali di base. Si è visto quindi come JSF introduca un ulteriore livello di astrazione nello stack dei servizi tipici di una applicazione web, analogamente a quanto fece Struts rispetto alle librerie della Servlet API. Con JSF lo sviluppatore non ragiona più in termini del paradigma richiesta/risposta , che ovviamente rimane alla base di qualsiasi applicazione web, ma ad un livello di astrazione più elevato considerando ogni elemento di una pagina web un componente e secondo una logica ad eventi. Le azioni dell‘utente sull‘interfaccia dell‘applicazione sono associati ad eventi che determinano delle operazioni sui componenti che la costituiscono. Partendo da questi due concetti di base , eventi e componenti, bisogna però capire come JSF gestisca e traduca questi concetti, estendendo i servizi comunemente forniti da altri framework quali Struts, nei quali comunque si era ancora strettamente legati alla gestione del paradigma richiesta/risposta analogamente a quanto si fa con una normale Servlet.
Una delle cose fondamentali da capire per poter affrontare in maniera consapevole lo sviluppo di una applicazione con JSF è il ciclo di vita di elaborazione di una richiesta descritto di seguito.
Il ciclo di vita di elaborazione delle richieste
Il ciclo di vita definisce il processo mediante il quale una richiesta viene gestita da una applicazione JSF dal momento in cui viene presa in carico dal controller fino alla generazione di una risposta al client. Chi ha esperienza di sviluppo di applicazioni web, e non solo, ha sicuramente familiarità con il concetto di “life-cycle” di un componente. Le Servlet hanno il loro ciclo di vita così come gli EJB. Qui per ciclo di vita ci riferiamo alle fasi che si susseguono nell‘elaborazione di una richiesta HTTP da parte di una applicazione JSF. Analizzando il ciclo di vita di elaborazione di una richiesta avremo modo di introdurre altri elementi di base di JSF quali ad esempio i backing beans e gli action events.
Il controller del framework JSF è ovviamente una servlet denominata FacesServlet che gestisce le richieste HTTP dei client.
JSF prevede sei fasi distinte nella gestione di un ciclo richiesta/risposta raffigurate nella Figura 1 tratta da [4]:
Figura 1 – Il ciclo di vita di JSF
Qui di seguito esaminiamo le diverse fasi prendendo lo spunto nel corso dell‘esposizione per introdurre ulteriori elementi di base di JSF.
Restore View
Come già detto ogni pagina di una applicazione JSF viene rappresentata da un albero di componenti che corrispondono ai vari elementi dell‘interfaccia grafica; il component tree è memorizzato di default nel server, o in alternativa nel client in un hidden field del browser. In questa fase il framework acquisisce il component-tree della pagina richiesta se non è la prima richiesta alla stessa oppure ne crea uno nuovo nel caso di prima richiesta.ÃÂ È molto importante osservare che JSF mantiene lo stato dei componenti tra una richiesta e l‘altra ad una vista per cui ad esempio mantiene i dati digitati in un form senza che lo sviluppatore se ne debba preoccupare. Se la richiesta non ha dati associati il framework redirige il flusso direttamente alla fase di RenderResponse, in genere quando la pagina è richiesta per la prima volta, altrimenti prosegue con la fase successiva.
Apply Requests
Come sappiamo bene ad una richiesta http possono essere associati dei dati da inviare al server, dati che sono ovviamente tutti delle stringhe indipendentemente dalla loro natura.
In questa fase il framework memorizza i dati associati alla richiesta nei componenti associati ai vari elementi della pagina. Infatti ogni componente che può essere associato ad un input dell‘utente ha un attributo submitted value che rappresenta il dato inviato dall‘utente. In questa fase il framework memorizza in questo attributo il valore contenuto nella request. Questa attività è detta decoding ed è la corrispondente dell‘encoding in cui un componente viene reso in formato HTML per essere interpretato dal browser. Al termine di questa fase tutti i componenti sono aggiornati con i dati acquisiti dalla richiesta pervenuta. Inoltre tutti gli eventi accodati vengono notificati ai propri listener. Ciò in determinate circostanze può provocare il salto diretto alla fase finale di renderizzazione della risposta e il salto delle successive fasi.
Process Validations
In questa fase a tutti i componenti dell‘albero che rappresenta la pagina in elaborazione viene richiesto di verificare che i valori presenti nella richiesta e memorizzati nella fase precedente sono validi quindi accettabili. Prima di poter essere validati i valori devono essere convertiti dal formato stringa al formato che essi hanno nel Model dell‘applicazione, date, numeri etc.. Questo viene fatto mediante i default converter del framework o mediante converter custom. La validazione dei valori viene effettuata direttamente dal componente o delegata ad un opportuno validator. Se i valori sono validi il framework passa all‘elaborazione della fase successiva altrimenti salta alla fase di renderizzazione della risposta accodando degli opportuni messaggi di errore. L‘utente ha così la possibilità di re-immettere i dati errati e ricominciare tutto il ciclo. Al termine della fase tutti gli eventi generati in essa vengono consumati dai propri listener il che può portare al passaggio diretto alla fase di Render Response.
Update Model Values
Come vedremo nel prossimo articolo JSF consente di associare il valore di un componente di una pagina, come ad esempio il valore di una text-box, ad un attributo di un JavaBean mediante una espressione simile a quelle tipiche di EL. Questi bean vengono detti backing-bean. I backing-bean sono dei JavaBean che consentono di interfacciare il livello di View dell‘applicazione con quello di Model. Generalmente contengono proprietà che vengono valorizzate con i valori immessi dall‘utente nella vista dell‘applicazione e metodi che effettuano elaborazioni in risposta ad eventi. I backing bean possono anche contenere riferimenti ai componenti che rappresentano gli elementi della vista, sui quali quindi è possibile effettuare delle operazioni. I backing-bean sono qualcosa di analogo a quello che nella tecnologia .NET si definisce “code-behind” e sono un elemento essenziale del livello Controller di JSF. Il framework consente di popolare automaticamente gli attributi di un backin-bean con i valori digitati nell‘interfaccia utente dell‘applicazione. Ciò può avvenire ovviamente solo quando i valori sono aggiornati, validi e del tipo corretto. La fase in cui avviene questa valorizzazione degli attributi del JavaBean associato ad un elemento di View è la Update Model Values. La cosa fondamentale da notare è che al termine di questa fase i dati digitati dall‘utente in una pagina web giungono validati e del tipo giusto in un bean che può essere utilizzato nel Model per le elaborazioni necessarie e questo senza che lo sviluppatore abbia dovuto preoccuparsene scrivendo del codice. Altra cosa importante è che i backing-bean associati alle viste sono regolari classi Java che rispettano le regole dei JavaBean ma che non devono estendere classi particolari o implementare interfacce come accadeva invece per i form di Struts. Si potrebbe dire che i backing-bean sono JavaBean che svolgono insieme le funzioni di una Action e di un ActionForm di Struts.
Come per le altre fasi anche al termine di questa gli eventi generati vengono consumati dai listener e possono condurre il ciclo al termine alla fase di Render Response. Altrimenti il ciclo prosegue con la fase successiva.
Invoke Application
In Struts era possibile associare l‘elaborazione conseguente alla sottomissione di un form ad una Action che mediante il proprio metodo execute elaborava la richiesta. In JSF come sappiamo quando un utente interagisce con un elemento della vista che rappresenta un comando , come un button o un link, vengono generati degli eventi. Esistono diverse tipologie di eventi che affronteremo in dettaglio quando si parlerà della gestione degli eventi di JSF. Gli eventi che vengono generati dai componenti come i button sono detti action events. Gli action events sono gestiti da listener che manco a dirlo si chiamano action listener e sono essenzialmente di due tipi: quelli che influenzano la navigazione dell‘applicazione e gli altri. I primi delegano il loro compito a degli action methods definiti nel backing-bean della vista.
Quando vedremo degli esempi concreti di una applicazione JSF sarà molto più chiaro come è possibile associare le azioni effettuate su un button ad un metodo di un backing bean e come mediante questi metodi sia possibile determinare il flusso di navigazione in una applicazione JSF. Quello che preme sottolineare ora e che è nella fase Invoke Application che tutti gli attributi dei backing-bean associati ai vari componenti della vista sono aggiornati e validi; in questa fase il framework notifica gli action events a tutti i listener registrati . In questa fase quindi vengono eseguiti gli action methods dei backing-bean della vista e quindi viene eseguita la logica corrispondente all‘azione effettuata dall‘utente sull‘interfaccia. Gli action methods possono determinare il passaggio del flusso di navigazione dell‘applicazione ad una nuova pagina.
Render Response
È l‘ultima fase del ciclo , e si occupa di memorizzare lo stato della vista che si sta elaborando e di generare la risposta per il client. In genere questo viene effettuato mediante un forward alla vista selezionata mediante la configurazione della navigazione che vedremo nel prossimo articolo.
Conclusioni
In questo articolo abbiamo introdotto alcuni concetti di base su Java Server Faces. L‘analisi del ciclo di vita dell‘elaborazione di una richiesta da parte di JSF ci ha consentito di introdurre alcuni concetti fondamentali quali ad esempio i backing-bean e gli action events. Sicuramente molte delle cose dette in questo articolo risulteranno più chiare quando si esaminerà una applicazione di esempio nella quale si vedrà la corrispondenza dei concetti esaminati con gli elementi di codice che la costituiscono. JSF è una tecnologia interessante che non è possibile però spiegare in poche righe nella sua interezza visto che ci sono diversi elementi fondamentali da introdurre dei quali non si è ancora parlato nel dettaglio quali ad esempio la gestione degli eventi. Una visione più chiara e di insieme del framework la si avrà solo quando saranno stati esposti tutti gli elementi di base di JSF.
Le fasi del ciclo di vita di elaborazione delle richieste sono state descritte con l‘intento di farne comprendere lo scopo senza entrare nel massimo dettaglio, cosa che richiederebbe un approfondimento ben diverso.
Nei riferimenti bibliografici, ed in particolare in [3], ne viene data comunque una ottima descrizione per coloro che fossero interessati ad un approfondimento.
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 Inc., 2004
[3] Kito D. Mann, “Java Server Faces In Action” Manning Publications Co., 2005
[4] Autori Vari, “The Java EE 5 Tutorial”, Sun Microsystems, febbraio 2007
Alfredo Larotonda, laureato in Ingegneria Elettronica, lavora da diversi anni nel settore IT. Dal 1999 si occupa di Java ed in particolare dello sviluppo di applicazioni web J2EE. Dopo diverse esperienze di disegno e sviluppo di applicazioni web per il mercato finanziario e industriale, si occupa ora in particolare di aspetti architetturali per progetti rivolti al mercato della pubblica amministrazione. È Sun Certified Enterprise Architect (SCEA) e ha inoltre conseguito le certificazioni SCJP, SCWCD 1.3, SCWCD 1.4, SCBCD.