CERCA SITEMAP FEED RSS 1280
Ultimo aggiornamento: 30 Agosto 2009

Introduzione a JavaServer Faces (JSF)

JavaServer Faces è una tecnologia lato server che viene utilizzata per costruire le interfacce utente delle web application.

JavaServer Faces è costituita da:
  • API per rappresentare i componenti UI e gestirne lo stato.
  • diverse librerie di tag per integrare tali componenti nelle pagine web e gestire gli oggetti lato server
Le interfacce utente create con Java Server Faces risiedono sul server e vengono visualizzate lato client, tipicamente la pagina web descrive i componenti dell'interfaccia utente utilizzando custom tags.

L'interfaccia web gestisce gli oggetti referenziati dalla pagina, questi che includono:
  • gli oggetti interfaccia utente corrispondenti ai tag nella pagina
  • gli ascoltatore di eventi, validatori e convertitori registrati su tali oggetti
  • oggetti javabeans che incapsulano dati e specifiche funzionalità
Uno dei più grandi vantaggi offerti da JavaServer Faces è la separazione fra comportamento e presentazione.
In realtà già le Java Server Pages implementano questa separazione ma a differenza delle JSF un'applicazione JSP non può mappare una richiesta HTTP verso il gestore di eventi di uno specifico componente.
La separazione della logica dalla presentazione consente inoltre ad ogni membro di un team di sviluppo di una web-application di focalizzare la sua attenzione su un pezzo del processo di sviluppo.
Il concetto di View Declaration Language introdotto da Java Server Faces 2.0 consente di dichiarare i componenti come avviene per le JSP.
Le facelet sono costruite secondo le specifiche JSF e costituiscono la tecnologia preferita per costruire web-application perchè offrono diversi vantaggi rispetto alla tecnnologia JSP.

Un’applicazione JavaServer Faces tipicamente include:
  • un insieme di pagine con i componenti interfaccia utente
  • un insieme di librerie di tag che consentono di aggiungere i componenti alle pagine
  • un insieme di backing beans ovvero javabeans che definiscono proprietà e funzioni per i componenti UI sulle pagine
  • uno o più file di configurazione che definiscono le regole di navigazione, l’inizializzazione di beans e custom object
  • un Deployment Descriptor
  • un insieme di custom object
  • un insieme di custom tags per inserire i custom object sulla pagina
I componenti UI che costituiscono i blocchi principali di costruzione sono configurabili e riutilizzabili per costruire interfacce utente.

JavaServer Faces fornisce un'architettura flessibile e ricca che include i seguenti elementi:
  • un insieme di UIComponent che sono delle classi che specificano lo stato e il comportamento dei componenti UI
  • un rendering model che definisce come renderizzare i componenti
  • un modello di eventi ed ascoltatori che definisce come gestire gli eventi sui componenti
  • un modello di conversione che definisce come registrare un convertitore di dati su un componente
  • un modello di validazione che definisce come registrare i validatori su un componente

Classi UI Component

La tecnologia JSF fornisce un insieme di componenti UI insieme alle interfacce associate al loro comportamento per specificare le funzioni interfaccia utente, gestire lo stato, mantenere il riferimento agli oggetti...
La classe di base è javax.faces.component.UIComponent mentre UIComponentBase definisce lo stato di default e il comportamento di un componente UI.

Le classi dei componenti incluse in JSF sono:
  • UIColumn: rappresenta una singola colonna di dati in un componente UIData
  • UICommand: rappresenta un controllo che produce un’azione quando è attivato
  • UIData: rappresenta un data binding ad una collezione di dati rappresentata da un’istanza DataModel
  • UIForm: incapsula un gruppo di controlli che sottomettono dati all’applicazione. Questo componente è analogo al tag “form” in HTML
  • UIGraphic: visualizza un’immagine
  • UIInput: preleva I dati dall’input utente.
  • UIMessage: visualizza un messaggio di errore localizzato
  • UIMessages: visualizza un insieme di messaggi di errore localizzati
  • UIOutcomeTarget: visualizza hyperlink nella forma di link o bottoni
  • UIOutput: visualizza I data di output di una pagina
  • UIPanel: gestisce il layout dei suoi componenit figlio
  • UIParameter: rappresenta parametri
  • UISelectBoolean: consente ad un utente di settare valori booleani in un controllo
  • UISelectItem: rappresenta un singolo item di un insieme
  • UISelectItems: rappresenta un insieme di item
  • UISelectMany: permette ad un utente di selezionare più item da un gruppo
  • UISelectOne: permette ad un utente di selezionare un item da un gruppo
  • UIViewParameter: rappresenta i parametri di una richiesta
  • UIViewRoot: rappresenta la radice dell’albero dei componenti
Oltre ad estendere la classe UIComponentBase, le classi componente possono implementare una o più interfacce di comportamento fra le quali:
  • ActionSource: indica che il componente può generare un action event.
  • ActionSource2: estende ActionSource e quindi fornisce le stesse funzionalità consentendo ai component l’uso dell’ Unified Expression Language per fare riferimenti ai metodo che gestiscono gli eventi
  • EditableValueHolder: estende ValueHolder e specifica caratteristiche addizionali per i componenti editabili
  • StateHolder: denota che un componente ha uno stato che deve essere salvato fra le richieste
  • ValueHolder: indica che il componente mantiene un valore locale
  • SystemEventListenerHolder: mantiene una lista di istanze di SystemEventListener per ogni tipo di SystemEvent

Component Rendering Model

L'architettura dei componenti JavaServer Faces è organizzata in maniera tale che la funzionalità dei componeneti è definita dalle classi componente mentre il rendering dei componenti è definito da una classe di rendering separata.

Questa organizzazione ha diversi benefici:
  • coloro che progettano i componenti possono definirne il comportamento una volta e creare più renderers ognuno dei quali definisce un diverso modo di visualizzare il componente sullo stesso client o su client differenti
  • gli sviluppatori delle applicazioni possono cambiare l'apparenza di un componente nella pagina selezionando i tag che rappresentano l'appropriata combinazione di componenti e renderer
Un render kit definisce come le classi componenti siano mappate in tag per un particolare client:
  • l'implementazione JSF include un render kit standard HTML per il rendering in browser web.
  • Il render kit definisce un insieme di classi Renderer per ciascun componente supportato, ogni classe renderer definisce un motodo differente di renderizzare un particolare componente.

Conversion model

Un'applicazione JSF può opzionalmente associare un componente ad un oggetto javabeans server-side detto backing bean e può quindi prelevare e settare i dati dell'oggetto facendo riferimento alle appropriate proprietà del componente.

Quando un componente è collegato ad un oggetto l'applicazione ha due view sui suoi dati:
  • la model view nella quale i dati sono rappresentati da tipi
  • la presentation view nella quale i dati sono rappresentati in modo tale da poter essere letti e modificati dall'utente
JSF automaticamente converte i dati di un componente fra queste due viste: se ad esempio un componente UISelectBoolean è associato ad una proprietà del bean booleana allora JSF convertirà i dati da string a booleano. Qualche volta può essere necessario convertire i dati di un componente in un altro tipo, per facilitare ciò vengono messi a disposizione dei convertitori (Converter) che vengono registrati presso i componenti.

Event and listener model

Le specifiche JSF definiscono tre tipi di eventi application event, system event e data-model event.
Gli application event sono propri di una particolare applicazione e sono generati da un UIComponent.
Un oggetto Event identifica il componente che ha generato l'evento e memorizza informazioni sull'evento; per poter gestire un evento l'applicazione deve fornire l'implementazione di un apposito listener ed effettuarne la registrazione presso il componente che genera l'evento.
Quando l'utente attiva il componente l'evento viene generato e quindi viene invocato il metodo del listener che processa quell'evento.
Esistono due tipi di application event:
  • gli action event: si verificano quando un utente attiva un componente che implementa l'interfaccia action-source
  • i value-change event: si verificano quando l'utente cambia il valore di un componente UIInput o una delle sue sottoclassi (ad esempio quando si seleziona una checkbox in una pagina).
I system event sono generati da un oggetto durante l'esecuzione di un'applicazione e sono associabili all'intera applicazione o a specifici componenti.
Un evento data-model infine occorre quando una nuova riga di un componente UIData è selezionata

Esistono due modi attraverso i quali un'applicazione può gestire un application event:
  • può implementare un listener che gestisce l'evento e registrarlo presso il componente
  • può implementare un metodo di un backing bean che gestisce l'evento e fare riferimento a questo metodo mediante un appropriato attributo nel tag componente.

Validation model

La tecnologia JSF supporta un meccanismo per validare localmente i dati di un componente editabile (es. textarea).
Questa validazione avviene prima che il corrispondente modello di dati venga aggiornato con i valori locali.
Ancora una volta, il validation model definisce un insieme di classi standard per effettuare controlli di validazione e anche un insieme di tag che corrispondono all'implementazione standard del Validator.
La maggior parte dei tag hanno un insieme di attributi per configurare le proprietà del validator, ad esempio possono essere indicati il valore minimo e massimo che un componente può assumere.
I validatori vengono registrati presso un componente innestando il tag del validator all'interno del tag del componente.
In aggiunta ai validatori registrati sui componenti è possibile dichiarare un validatore di default che è registrato su tutti i i componenti UIInput dell'applicazione (dichiarandolo nei file di configurazione dell'applicazione).
  <faces-config>  
    <application>
      <default-validators>
        <validator-id>javax.faces.Bean</validator-id>
      </default-validators>
    </application>
  </faces-config>
Il validation model consente anche di creare validatori custom, in particolare si può:
  • implementare l'interfaccia Validator
  • implementare un metodo in un backing bean che effettua la validazione.
Nel primo caso si può:
  • registrare il validatore presso l’applicazione
  • creare un custom tag utilizzando un validator tag per registrare il validatore sul componente

Navigation model

Il Navigation Model consente di definire la navigazione delle pagine fornendo un processo addizionale necessario a scegliere la sequenza nelle quali queste devono essere caricate. In JSF la navigazione è un insieme di regole per scegliere la successiva pagina che deve essere visualizzata dopo un'azione (es. click su un link).
Queste regole sono dichiarate in uno o più file di configurazione utilizzando un insieme di elementi xml.
  <navigation-rule>  
    <description></description>
    <from-view-id></from-view-id>
    <navigation-case>
      <from-action></from-action>
      <from-outcome></from-outcome>
      <if></if>
      <to-view-id></to-view-id>
    </navigation-case>
  </navigation-rule>
Per gestire la navigazione nelle applicazioni più semplici si occorre agire nel seguente modo:
  • si definiscono le regole di navigazione nel file di configurazione
    <navigation-rule>
      <from-view-id>/successiva.xhtml</from-view-id>
      <navigation-case>
        <from-outcome>ok</from-outcome>
        <to-view-id>/precedente.xhtml</to-view-id>
      </navigation-case>
    </navigation-rule>
    
  • si fa riferimento ad una particolare stringa nell'attributo action del bottone o dell'hyperlink che viene utilizzata per selezionare una regola di navigazione.
    <h:commandButton id="submit" action="ok" value="Submit" />
    
In applicazioni più complicate la selezione della pagina che deve essere visualizzata può dipendere dal valore restituito da un metodo di un backing bean: questo comporta una ulteriore elaborazione per determinare tale valore.

Occorre quindi fare riferimento a questo metodo nell'attributo action dell'elemento considerato:
<h:commandButton id="submit" action="#{mioBean.getStato}" value="Submit" />
Quando l'utente clicca su un bottone rappresentato da un tag viene generato un evento gestito dall'ActionListener di default il quale chiama il metodo referenziato dal tag del componente. Questo restituisce un valore logico all’ActionListener il quale provvede ad inviarlo al NavigationHandler; quest’ultimo seleziona la pagina che deve essere visualizzata cercando una corrispondenza fra il valore logico e il metodo che l'ha generato all'interno delle regole di navigazione presenti nel file di configurazione.

In particolare:
  • Viene selezionata la regola di navigazione che corrisponde alla pagina correntemente selezionata.
  • Si cerca inizialmente una corrispondenza doppia fra valore (outcome) e metodo che l’ha generato all’interno delle regole di navigazione
  • Se tale ricerca fallisce si cerca un match con il solo valore logico (outcome)
  • Se fallisce anche questa si cerca un match con il riferimento al metodo che ha prodotto l'outcome
  • Se nessun match ha successo allora viene visualizzata la pagina corrente.