Proseguendo sulla scia di quanto anticipato nel relativo al lifecycle JSF (l’avete letto, vero?), proviamo a mettere un po’ le mani in pasta, cominciando dall’implementazione di una piccola vista e del relativo backing bean.
Un backing bean non è altro che una classe Java, dotata di un costruttore senza argomenti e con alcuni attributi che saranno “legati” (faranno quindi da binding, cioè da legame) ai componenti JSF o al valore in essi contenuto. Per quanto riguarda il costruttore no-args, esso (come già sapete) è implicito in Java e quindi potremmo anche non scriverlo nel codice, ma solo se non ve ne è già uno presente che possiede dei parametri: nel qual caso, dovremmo implementare il no-args per consentire a JSF di istanziare il backing bean in maniera corretta.
Come ulteriore precauzione facciamo implementare dal nostro BB (oramai ne siamo amici e lo possiamo chiamare con un’abbreviazione) l’interfaccia marker Serializable
, che, con zero metodi da implementare (sennò che marker sarebbe?), ci permette di restare tranquilli anche se la nostra applicazione fosse deployata in ambiente clusterizzato (in merito, leggere questo autorevolissimo di ).
Buttiamo giù quindi un po’ di codice per il BB:
package it.cosenonjaviste.backingbeans;
import java.io.Serializable;
import javax.faces.component.html.HtmlInputText;
import javax.faces.component.html.HtmlOutputText;
import org.ajax4jsf.model.KeepAlive;
@KeepAlive
public class HelloBackingBean implements Serializable
{
/* proprietà che è il corrispondente
Java JSF del campo di input della form */
private transient HtmlInputText nomeBinding;
/* proprietà che conterrà il valore inserito
nel campo di input della form */
private String nome;
/* proprietà che è il corrispondente
Java JSF del campo di output della form */
private transient HtmlOutputText outputComponent;
/* proprietà che conterrà il valore
mostrato nell'output della form */
private String outputValue;
public HelloBackingBean() {
outputValue = "Chi sei?";
}
public HelloBackingBean(String nome) {
this.nome = nome;
resetOutputValue();
}
private void resetOutputValue() {
outputValue = "Chi sei?";
}
public void riconosciUtente() {
outputValue = "Ora ti riconosco! Ciao " + nome;
}
public void resetValues() {
resetOutputValue();
nome = null;
}
public HtmlInputText getNomeBinding() {
return nomeBinding;
}
public void setNomeBinding(HtmlInputText nomeBinding) {
this.nomeBinding = nomeBinding;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public HtmlOutputText getOutputComponent() {
return outputComponent;
}
public void setOutputComponent(HtmlOutputText outputComponent) {
this.outputComponent = outputComponent;
}
public String getOutputValue() {
return outputValue;
}
public void setOutputValue(String outputValue) {
this.outputValue = outputValue;
}
}
La nostra semplice GUI in JSF/RichFaces sarà invece di questo tipo e contenente un particolare tipo di notazione #{nomeBB.property}
, chiamata Expression Language:
Avendo BB e pagina a disposizione, iniziamo a tessere le fila del discorso per vedere come interagiscono fra loro e con il framework in genere.
Come prima cosa, è necessario registrare il nostro BB all’interno del file faces-config.xml per far sì che possa essere utilizzato all’interno della nostra pagina (sulla falsa riga di Spring). Inseriamo quindi il seguente tag:
helloBB
it.cosenonjaviste.backingbeans.HelloBackingBean
request
In tal modo, il nostro backing bean diventa un managed bean, cioè un bean gestito dal framework JSF, che si prende il compito di istanziare tale classe quando ce n’è bisogno. La “frequenza” di istanziazioni (che porta quindi ad una chiamata del relativo costruttore e al reset dello stato della classe, cioè dei suoi attributi) dipende dallo scope del backing bean. Il BB può essere registrato a livello request (cioè ad ogni richiesta HTTP viene ricreato), a livello session (il suo stato perdura all’interno di un’intera sessione HTTP) o a livello application (il suo stato viene mantenuto a livello di applicazione, quindi in comune tra sessioni diverse).
Noi lo abbiamo registrato a livello request, ma abbiamo annotato la classe con @KeepAlive
, un’annotation di JBoss RichFaces che ci permette di allungare la vita dello stato del BB in misura intermedia fra request e session; in particolare, esso si mantiene fra request diverse all’interno della stessa pagina oppure anche fra pagine diverse se collegate tramite navigazione JSF senza redirect (per approfondimenti, leggete questo di ).
Come inciso, vi dico anche che è possibile far inizializzare dal framework alcune property del BB. E’ sufficiente censire tali proprietà all’interno del faces-config.xml, assegnando loro il valore desiderato (che può essere anche un’istanza di un altro BB..ci pensa JSF a generarla e iniettarla nel nostro BB!):
goodbyeBB
.....
.....
.....
helloBB
it.cosenonjaviste.backingbeans.HelloBackingBean
request
//questo è il nome della property che dovrebbe esserci nel nostro HelloBackingBean
goodByeBackingBean
//questo fa riferimento al nome con cui è censito l'altro BB
#{goodbyeBB}
valoreDiProva
10
Immediatamente dopo la chiamata (“automatica”) del costruttore di HelloBackingBean, vengono chiamati i metodi set delle property da popolare, cosicchè noi poveri programmatori potremo usufruire di tali dati in modo corretto senza stare a fare new o inizializzazioni dentro la classe Java (come dicono quelli bravi come Andrea, stiamo assistendo alla cosiddetta , tramite la cui implementazione, detta Dependency Injection, è il framework che, fin dove può, ci aiuta nello sviluppo fornendoci già inizializzati gli strumenti di lavoro).
Da sottolineare,inoltre, che i metodi getter e setter per le property del BB richiamate nella pagina tramite EL sono NECESSARI, in quanto sfruttati dal framework JSF per accedere in lettura e scrittura alle property stesse. I commandButton, invece, effettuano la chiamata di due action (che, vi ricordo, sono metodi senza argomenti che possono restituire String
o void
). In questo caso, abbiamo utilizzato 2 < h:commandButton>, cioè componenti JSF puri, che provocano la submit e il processing dell’intera form: nel prossimo post, vedremo come utilizzare le funzionalità AJAX delle RichFaces per un processing/rendering parziale della pagina.
Inoltre abbiamo utilizzato il modificatore transient per le property di binding dei componenti (che utilizzeremo nel prossimo post!): questo perchè, essendo oggetti non serializzabili, in ambiente distribuito (es. server in cluster) causarebbero eccezioni nel salvataggio dello stato del BB, mentre tale modificatore ne impedisce a runtime la serializzazione.
Beh, a questo punto abbiamo finito! Vediamo quindi come compare la nostra pagina appena la visualizziamo sul browser:
e dopo aver compilato il campo di input con il nome e premuto il pulsante Submit:
Ultima curiosità: il titolo sull’header del pannello è inserito grazie al tag con l’attributo name valorizzato necessariamente a “header”. Al prossimo post…e alla prossima review della nostra pagina!