Essere o non essere? Request o Session? Questo non è più un problema… Grazie a RichFaces abbiamo a disposizione la soluzione al dilemma shakespeariano.
Come sappiamo, la comunicazione tramite web è basata sul protocollo HTTP che di natura è senza stato, per cui ogni richiesta (request) è indipendente dalla precedente. I server web però implementano un meccanismo che permette di riconoscere se il client che chiama è sempre lo stesso, creando una sessione univoca (session) che può essere sfruttata per mantenere memoria della comunicazione.
Ad ogni richiesta il browser invia l’identificativo della sessione al server (memorizzato in un cookie) in modo da essere riconosciuto. Se l’intervallo tra due richieste non supera una certa soglia (solitamente 30 minuti), il client viene riconosciuto e può accedere a quelle informazioni legate alla propria sessione utente, altrimenti la sessione viene invalidata e tutti i dati in essa memorizzati vengono persi.
Il JSF, definendo gli scope, cioè il tempo di vita dei backing bean di una applicazione web, si basa proprio su questa classica infrastruttura: i backing bean in request vengono creati e distrutti ad ogni richiesta del client, mentre quelli in session rimangono attivi fino al timeout della sessione. Quest’ultimo comportamento può essere molto oneroso dal punto di vista di occupazione della memoria e della serializzazione sella sessione web in ambienti cluster, come già accennato in un .
Con l’ausilio del framework abbiamo a disposizione un nuovo scope di tipo conversazionale, grazie all’annotazione @KeepAlive
applicabile su un backing bean in request:
@KeepAlive
public class MyBackingBean implements Serializable {
//My Code...
}
Uno scope conversazionale applicato ad un backing bean configurato originariamente per stare in request ci permette di mantenere in vita il backing bean tra più richieste all’interno della stessa pagina e verrà eliminato solo quando la lasceremo. Per lo meno questo è quello che dice giustamente la documentazione, ma c’è da porre particolare attenzione. Ovviamente non è che RichFaces fa magie: semplicemente tiene in sessione un oggetto a cui aggancia i nostri backing bean, che decide poi di eliminare al cambio della vista. E’ proprio il “come” viene determinato il cambio della vista che può creare un po’ di confusione.
Per come è strutturata la navigazione del framework, i backing bean in KeepAlive vengono distrutti solo quando la navigation-rule del faces config, che ci permette di navigare tra le pagine tramite le action, è stata dichiarata
, altrimenti il backing bean rimane agganciato alla sessione fino al timeout. Utilizzare il
comporta però una doppia chiamata al server: ad ogni action, il client chiama il server con una chiamata POST, il quale, se prevede una navigazione, ritorna l’indirizzo verso cui dirottare il client (nel parametro ‘Location’ dell’header della response), che a sua volta effettuerà il fetch della nuova pagina con una nuova chiamata GET al server. Quest’ultimo tipo di chiamata fa comprendere al server che la conversazione sulla vista precedente è finita e invalida lo scope KeepAlive. Lo stesso risultato si ha se effettuo una chiamata ad una pagina tramite il tag
Piuttosto che cambiare le regole di navigazione ed introdurre il redirect, può essere conveniente attivare lo scope KeepAlive solo per le conversazioni Ajax:
@KeepAlive(ajaxOnly = true)
public class MyBackingBean implements Serializable {
//My Code...
}
In questo modo potremo fare affidamento sullo stato del backing bean durante conversazioni ajax ed avere al contempo la garanzia che questo venga distrutto non appena venga effettuata qualalsiasi chiamata non-Ajax al server, sia essa di GET o POST.
Conclusioni
L’annotazione KeepAlive di RichFaces è molto utile per chi lavora con le versioni del JSF inferiori alla 2.0. Nella nuova versione infatti è stato introdotto nativamente questo scope grazie all’annotazione @ViewScoped
che ha lo stesso comportamento di KeepAlive: il backing bean viene mantenuto vivo finché rimaniamo nella stessa vista e viene invalidato solo a seguito di una chiamata GET ad una pagina.
Pensando alla semantica dei metodi forniti dal protocollo HTTP questo comportamento ha anche senso. Il metodo GET infatti serve per recuperare (appunto get) una risorsa dal server: chiamando una pagina con il metodo GET sto dicendo quindi al server che voglio accedere ad una risorsa che in questo caso è una pagina (che sia una nuova o sempre la stessa). Il metodo POST invece serve per inviare informazioni al server e non a caso è il metodo usato dalle action JSF: è questo il motivo per cui, nel caso in cui non si usi redirect nelle regole di navigazione, si verifica quel fastidioso sfasamento tra l’URL sulla barra degli indirizzi e il contenuto della pagina.
Pingback: ()