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
|