MokaByte 71- Febbraio 2003 
JSP e Web User Interface
I parte: Java Server Faces
di
Lavinio Cerquetti
Terminata la serie di articoli inerenti la JSP Standard Tag Library ([1] - [4]) proseguiamo l'esplorazione di API e protocolli relativi al mondo delle interfacce utente Web-based in Java rivolgendo la nostra attenzione ad un framework ancora in via di sviluppo, ma già estremamente interessante: Java Server Faces [5]. Java Server Faces, il cui nome risulterà forse già noto ad alcuni lettori, è un framework Java per la realizzazione di interfacce HTML componentizzate, state-aware, riusabili ed event-driven, destinato con tutta probabilità a rappresentare uno standard in tema di Web User Interface. Per capire i motivi per cui abbiamo deciso di analizzare un prodotto di cui non solo non è ancora avvenuto il primo rilascio definitivo, ma che tecnicamente si trova ad oggi in uno stato di pre-beta - tali sono infatti da considerarsi le Early Access Release disponibili da Sun - è necessario fare un passo indietro

Il problema
Chi ha seguito la storia delle Servlet API sin dai loro inizi non ne può non ricordare con un misto di nostalgia e di eccitazione il rilascio iniziale – avvenuto nell'ormai lontano 1997 - ed i primissimi esempi di utilizzo apparsi nel sito Sun, in cui poche righe di codice generavano pagine Web dinamiche, aprendo di fatto al linguaggio Java quelle porte della programmazione in ambiente Web che ne avrebbero decretato il successo e che ci hanno oggi condotti, tramite un'impressionante serie di evoluzioni e migliorie, a paradigmi ed architetture del livello di J2EE.

Eppure già in quei primissimi esempi di servlet – nei quali le pagine dinamiche venivano prodotte tramite delle semplici print() contenenti del codice HTML – è possibile individuare le origini di una questione fondamentale e tuttora irrisolta nella programmazione di applicazioni Web in Java: stiamo parlando del rapporto tra il programma, inteso come insieme di conoscenze e di comportamenti, e la sua interfaccia utente.

La piattaforma di fruizione di un'applicazione distribuita Web-based consiste infatti per definizione in un browser, cosa che comporta inevitabilmente la necessità di realizzarne l'interfaccia utente in linguaggio HTML.
Come tuttavia tale interfaccia utente venga costruita a run-time e sino a che punto l'applicazione stessa debba essere dipendente dal linguaggio HTML, in tutte le sue molteplici incarnazioni, nonché dalle caratteristiche del browser dell'utente, è un problema ancora aperto.
Se è vero che nessun programmatore professionista si sognerebbe di mettere in dubbio il bisogno di una quanto più radicale separazione tra forma - HTML, XHTML, DHTML, XML, WAP - e contenuto (business-logic) di una qualsiasi applicazione distribuita, arrivando a teorizzare che in, in fondo, le diverse interfacce utente non dovrebbero essere altro che 'viste' e punti di accesso separati ad un insieme unico di logica e di comportamenti, è purtroppo altrettanto vero che non esiste nel mondo Java nessun paradigma o framework che si possa considerare standard in tal senso, situazione che ha portato ad un proliferare di soluzioni diverse e spesso stridenti, e che di fronte all'ormai agguerrita concorrenza di soluzioni alternative – prima fra tutti .NET di Microsoft - rischia di far perdere definitivamente a Java il treno delle Web application di livello medio, caratterizzate da scheduling aggressivi e da team di sviluppo non sempre di altissimo livello, le quali costituiscono tuttavia la grande maggioranza del mercato.

L'assenza di un punto di riferimento intorno al quale la comunità degli sviluppatori e dei produttori di tool potesse aggregarsi ha infatti impedito la nascita di un insieme di strumenti di sviluppo coesi ed evoluti in grado di trasformare in commodity la realizzazione di GUI Web-based in maniera analoga a quanto già da tempo possibile in ambito client-server.
È quasi paradossale notare come la creazione in modalità RAD di interfacce utente HTML, che oggi viene considerata una delle più importanti frecce all'arco di .NET, risulti già perfettamente possibile da quattro anni a questa parte agli sviluppatori Delphi.
Java, al contrario, non è sino ad oggi stato in grado di fornire una valida risposta a questa esigenza e nessuno dei tanti framework open-source o proprietari è riuscito né ad affermarsi come standard né a coprire in maniera soddisfacente quest'area funzionale, a partire dalle soluzioni più generaliste – come Cocoon, JADE (di recente ribattezzato SOFIA), Struts e Tapestry – per arrivare a quelle più votate allo strato di interfaccia utente – quali Millstone, TICL, XUL o l'originale Droplets. Riferimenti a questi ed altri framework sono contenuti nella sezione di bibliografia del presente articolo (riferimenti [6] - [23]).

 

Java Server Faces
Sun stessa ha percepito la gravità di questa situazione ed ha promosso la nascita della Java Specification Request 127 [24], alias Java Server Faces, al cui Expert Group collaborano tutti i 'grandi nomi' dell'informatica Java-related – con in prima fila Sun, IBM, Oracle, Fujitsu e Hewlett-Packard – assieme ai principali produttori di tool di sviluppo ed attori della scena open-source quali BEA, Borland, Macromedia e l'Apache Group.
I fini di JSR-127, attiva da Maggio 2001, consistono specificamente nella realizzazione di un framework per la realizzazione di interfacce utente Web-based componentizzate, state-aware, espandibili, event-driven, indipendenti dal markup language utilizzato dalla piattaforma di fruizione e dal contesto di esecuzione.
Analizziamo più nel dettaglio tali requisiti:

  • Per componentizzazione si intende la possibilità di considerare gli elementi dell'interfaccia alla stregua di 'unità di assemblaggio' sulla scorta delle quali realizzare elementi GUI più complessi o intere interfacce utente. In particolare le specifiche Java Server Faces si pongono l'obiettivo di risultare 'tool-friendly', in maniera da essere facilmente integrabili in ambienti di sviluppo RAD, consentendo agli sviluppatori di realizzare in breve tempo e con skill minimi interfacce utente per applicazioni Web e distribuite con la stessa semplicità offerta da ambienti quali .NET e Delphi, semplicemente 'collegando' elementi di interfaccia a componenti di gestione e di business logic lato server tramite catene di eventi;
  • Java Server Faces intende risolvere in maniera definitiva anche la questione della gestione dello stato nelle interfacce Web, liberando lo sviluppatore dal bisogno di salvare e ripristinare lo stato di tutti i componenti di interfaccia utente ad ogni visualizzazione di pagina. L'obiettivo è quello di rendere gli elementi GUI 'intelligenti', dotandoli della possibilità di validare in prima persona i dati inseriti dall'utente e di archiviare e ricaricare in maniera automatica ed on-demand il proprio stato da componenti / Bean di memorizzazione lato server, denominati in gergo JSF 'model object', facili da realizzare ed integrabili con architetture evolute quali JDO ed EJB;
  • l'analisi dell'attuale stato dei framework di interfaccia utente in Java ha spinto i membri dell'Expert Group a considerare l'espandibilità come un fattore imprescindibile: JSF si prefigge l'obiettivo di semplificare la customizzazione di rendering e di comportamenti, così come la creazione di elementi di interfaccia utenti complessi e di utilizzo generale; l'obiettivo è fornire una specifica ed un insieme di componenti GUI di 'primo livello', lasciando ai produttori di tool la possibilità di personalizzare ed espandere l'offerta di elementi di interfaccia utilizzabili in applicazioni Web e distribuite;
  • assieme alla questione dello stato, uno dei punti cardine di JSF è rappresentato dalla definizione di un nuovo paradigma di event handling, che avvicini la programmazione in ambito Web agli idiomi di gestione asincrona e discreta degli eventi già noti agli sviluppatori in ambienti GUI client-server, sfruttando quando disponibili le capacità della piattaforma di fruizione per localizzare presso il client il processing di determinati eventi;
  • l'indipendenza dal markup language (HTML, DHTML, XML) viene ottenuta grazie alla completa separazione tra forma e comportamento dei componenti GUI: ogni modello di interazione lato server (quali 'seleziona un elemento da una lista', 'permetti all'utente di inserire manualmente dei dati') viene realizzato a livello client tramite dei Renderer diversificati, i quali producono un'interfaccia utente in grado di soddisfare i requisiti funzionali del server al meglio delle possibilità della piattaforma di fruizione dell'utente;
    la nozione di indipendenza dal markup language, ossia dal contesto lato client, viene estesa anche all'ambito lato server, il quale - al fine di garantire la massima longevità di Java Server Faces - è indipendente dallo stesso paradigma Java Server Pages ed è stato progettato direttamente ed unicamente in funzione delle Servlet API.

L'ambiziosità di questo progetto ne giustifica perlomeno in parte i lunghi tempi di gestazione: sono comunque già disponibili la seconda versione Early Access di JSF ed il Public Draft 1.0 delle sue specifiche [25].
Per quanto buona parte di Java Server Faces sia ancora in uno stato piuttosto fluido – in particolare i layer di gestione degli eventi – l'Early Access Release ci consente di farci un'idea sufficientemente precisa dell'architettura di questa API, che 'voci di corridoio' danno come destinata ad essere finalizzata nella sua versione 1.0 entro quest'anno, così come di cominciare ad utilizzarla in progetti di test.
Si noti infine che Java Server Faces sfrutta internamente diverse API Java open source rilasciate in seno al gruppo Apache e divenute ormai standard de facto. Fra queste va sicuramente menzionato Struts [15], forse il framework Java generalista di maggior successo in assoluto, verso il quale JSF si propone espliciti obiettivi di integrazione e nei cui confronti – con particolare riferimento al package struts-html, i cui tag sono destinati ad andare in overlapping con Java Server Faces - intende fornire espliciti tool di migrazione.

 

L'architettura di Java Server Faces
Chiarito in generale il contesto in cui Java Server Faces si colloca e gli obiettivi che ne caratterizzano il design, passiamo all'analisi strutturale di questo framework.
L'attuale contesto di utilizzo di JSF è all'interno di applicazioni J2EE, in qualità di layer deputato all'implementazione di interfacce utente Web / Internet.
Nella sua attuale implementazione Java Server Faces è in effetti una tag library di JSTL, grazie al quale risulta perfettamente integrato con JSP e con tutti i protocolli ed API del mondo Java Enterprise, che le nostre applicazioni JSF potranno sfruttare trasparentemente.
Un'interfaccia utente realizzata in JSF consisterà dunque in un insieme di pagine JSP, al cui interno utilizzeremo i tag Java Server Faces per 'disegnare' elementi di interfaccia utente, ed in una pluralità di oggetti Java delegati a rappresentare e validare lo stato dei suddetti componenti ed a gestire il processing degli eventi, le funzionalità di navigazione ed il ciclo di vita dell'applicazione.
I tag Java Server Faces verranno tradotti in elementi di interfaccia utente solamente a run-time ed in funzione delle caratteristiche e possibilità della piattaforma di fruizione dell'utente.
I quattro elementi fondanti di JSF, che analizzeremo più nel dettaglio nel corso della nostra esplorazione, sono:

  • i componenti di interfaccia utente lato server;
  • gli elementi di interfaccia utente lato client;
  • i model object, vale a dire i Bean - accoppiati ai componenti di interfaccia utente - che ne rappresentano e memorizzano lo stato;
  • l'oggetto ApplicationHandler, ossia il gestore di eventi globali dell'applicazione JSF.

Per capire come tali elementi si integrino e comunichino, volgiamo la nostra attenzione al ciclo di vita di una pagina HTML nel quadro di un'applicazione Java Server Faces.

Il ciclo di vita di una pagina JSF
Dal momento che il framework Java Server Faces introduce alcune significative astrazioni a livello di Web application, in particolare per quanto riguarda la gestione dello stato, degli eventi e della navigazione, è lecito attendersi che il ciclo di vita di una pagina HTML presenti delle novità.
In effetti, l'interazione request / response HTML tra client e server avviene in JSF in sette diverse fasi:

  • Reconstitute Request Tree: essa rappresenta l'avvio di un'interazione JSF, e coincide con una richiesta effettuata dall'utente, tipicamente tramite un click su di un bottone o su di un link. In questa fase Java Server Faces esamina la struttura dei componenti della pagina, costruendone una rappresentazione gerarchica e collegandoli ai rispettivi gestori di eventi e di validazione;
  • Apply Request Values: viene effettuata un'iterazione in modalità preorder sull'albero dei componenti costruito nel punto precedente, dando ad ogni elemento UI la possibilità di estrarre dalla richiesta HTML e di memorizzare le proprie informazioni aggiornate di stato. Questa fase è anche responsabile per l'immissione in una coda apposita degli eventi associati alla richiesta corrente e di eventuali segnalazioni di errore legate a stati non consentiti;
  • Handle Request Events: Ogni evento in grado di causare un aggiornamento dell'interfaccia utente viene notificato a tutti gli elementi UI presenti nell'albero dei componenti, i quali aggiornano di conseguenza il proprio stato. In base alla loro reazione viene costruito l'albero di elementi UI di output, che rispecchia lo stato dell'interfaccia in seguito al processing degli eventi;
  • Process Validations: in questa fase vengono elaborate le informazioni relative ai gestori di validazione. Lo stato di ogni elemento dell'albero dei componenti per cui sia stata richiesta una procedura di controllo viene inoltrato alle regole di validazione e, se risulta non ammissibile, un apposito messaggio di errore viene inserito nel contesto della pagina corrente;
  • Update Model Values: se lo stato della pagina è valido viene effettuata una nuova iterazione sull'albero dei componenti di output, salvando lo stato di ogni elemento UI nel corrispondente model object;
    Invoke Application: in questa fase vengono gestiti quegli eventi che causano un impatto globale a livello di applicazione e che sono tipicamente associati a funzionalità di navigazione (submit di un form ovvero attivazione di un hyperlink). Il controllo di tali eventi spetta all'oggetto ApplicationHandler registrato a livello di JSF all'avvio dell'applicazione;
  • Render Response: essa costituisce l'ultima fase del ciclo di vita di una pagina in ambiente Java Server Faces, e consiste in un'iterazione sull'albero dei componenti di output al fine di invocare su ognuno di essi il Renderer desiderato, ovvero la classe JSF incaricata di tradurre il componente in una rappresentazione comprensibile alla piattaforma lato client. Il risultato di questa fase è, ad esempio, un blocco di informazioni HTML che viene ritornato al browser utente, terminando così la procedura di request / response di pagina.

 

I componenti di interfaccia utente lato server
Molti, leggendo il titolo di questo paragrafo, avranno già notato l'ossimoro: come può un componente di interfaccia utente, vale a dire qualcosa che per definizione è strettamente legato al client, esistere 'lato server' ?
La risposta è che JSF mantiene lato server la conoscenza dei 'modelli di interazione' di un'interfaccia utente, vale a dire quell'insieme di comportamenti, azioni e reazioni - gestione degli eventi, dialogo con i model object per la gestione dello stato e con gli elementi UI lato client per il rendering dei componenti - che identificano in maniera univoca un elemento di interfaccia utente indipendentemente dalle sue peculiarità di rappresentazione visiva.

I componenti UI lato server sinora presenti in JSF sono sette e rappresentano gli elementi base comuni alla grande maggioranza delle interfacce utente. Essi sono destinati ad essere ampliati, sia direttamente a livello di specifiche Java Server Faces sia tramite librerie di componenti di terze parti:

  • UIOutput: rappresenta un insieme di informazioni testuali da produrre in output;
  • UITextEntry: questo modello di interazione rappresenta un elemento di interfaccia tramite il quale l'utente può inserire delle informazioni in formato testuale;
  • UISelectBoolean: consente all'utente di fornire un'informazione di tipo booleano;
  • UISelectOne: permette all'utente di selezionare un elemento all'interno di una lista a valori predefiniti;
  • UICommand: rappresenta un elemento di interfaccia in grado di generare un evento all'atto della sua 'attivazione' da parte dell'utente;
  • UIForm: questo componente UI lato server raggruppa un insieme di controlli logicamente correlati in una sorta di 'unità transazionale' ed è affine al tag <form> in HTML;
  • UIPanel: raggruppa un insieme di elementi di interfaccia utente al fine di coordinarne la modalità di presentazione a video, svolgendo un ruolo paragonabile ai Layout Manager in ambiente Swing.

Conclusioni
Abbiamo iniziato l'analisi di Java Server Faces, il framework Java per la realizzazione di interfacce utente ad applicazioni Web e distribuite, esaminandone le motivazioni e gli obiettivi, nonché le possibilità di utilizzo in ambito J2EE e la sua struttura tecnica generale.
Nel prossimo articolo termineremo la disamina dei blocchi principali di JSF e ne sperimenteremo sul campo le possibilità di integrazione, utilizzandolo per dotare NetView, la nostra applicazione Web di studio, di un semplice pannello di configurazione.

 

Bibliografia
[1] Lavinio Cerquetti: “JSP 1.2: La JSP Standard Tag Library – I parte”, Mokabyte N. 67 - Ottobre 2002
[2] Lavinio Cerquetti: “JSP 1.2: La JSP Standard Tag Library – II parte”, Mokabyte N. 68 – Novembre 2002
[3] Lavinio Cerquetti: “JSP 1.2: La JSP Standard Tag Library – III parte”, Mokabyte N. 69 – Dicembre 2002
[4] Lavinio Cerquetti: “JSP 1.2: La JSP Standard Tag Library – IV parte”, Mokabyte N. 70 – Gennaio 2003
[5] JSF – Java Server Faces: http://java.sun.com/j2ee/javaserverfaces
[6] Casabac: http://www.casabac.com
[7] Cocoon: http://xml.apache.org/cocoon
[8] Droplets: http://www.droplets.com
[9] Echo: http://www.nextapp.com/products/echo
[10] ECS: http://jakarta.apache.org/ecs
[11] FreeMarker: http://www.freemarker.org
[12] Luxor XUL: http://luxor-xul.sourceforge.net
[13] Millstone: http://www.millstone.org
[14] SOFIA (ex JADE): http://sourceforge.net/projects/salmon
[15] Struts: http://jakarta.apache.org/struts
[16] Swinglets: http://www.swinglets.com
[17] Tapestry: http://jakarta.apache.org/proposals/tapestry
[18] TICL: http://www.kobrix.com
[19] Turbine: http://jakarta.apache.org/turbine
[20] Velocity: http://jakarta.apache.org/velocity
[21] WebMacro: http://www.webmacro.org
[22] WebObjects: http://www.apple.com/webobjects
[23] wingS: http://wings.mercatis.de
[24] JSR 127 – Java Server Faces: http://www.jcp.org/jsr/detail/127.jsp
[25] Java Server Faces – Early Access Release 2 e 1.0 Early Access Draft Specification: http://java.sun.com/j2ee/javaserverfaces/download.html


Lavinio Cerquetti si occupa di design e sviluppo del software in ambienti distribuiti ed in architetture J2EE multi-tier. Può essere contattato all’indirizzo di e-mail lcerquetti@mokabyte.it

MokaByte® è un marchio registrato da MokaByte s.r.l. 
Java®, Jini® e tutti i nomi derivati sono marchi registrati da Sun Microsystems.
Tutti i diritti riservati. E' vietata la riproduzione anche parziale.
Per comunicazioni inviare una mail a info@mokabyte.it