Comment gérer l'expiration de session dans JSF
Question: Comment échaper au pièges des sessions qui expirent en JSF ?
Coté interface:
Notamment avec JSF 1.2. RI Quand on clique sur une page d'une session expirée, des erreurs sont affichées dans la trace et on a une page blanche.
La page est obtenue par l'envoi d'un formulaire dans lequel il y a une variable ViewState. Le serveur prend cela pour un POST BACK. Il essaie donc de récupérer les infos de la vue. Quand ces infos sont stockées sur le serveur et que la session a expiré, il n'y arrive pas et lance une erreur. Si on a choisi de sauver les informations sur le client, normalement ce problème n'arrive pas.
Si on cherche uniquement à re-obtenir la page, le mieux est de revenir au mode compatibilité JSF 1.1 en mettant ceci dans le web.xml
Code:
1 2 3 4
| <context-param>
<param-name>com.sun.faces.enableRestoreView11Compatibility</param-name>
<param-value>true</param-value>
</context-param> |
Si on veut faire quelquechose de plus particulier, il faut détecter le cas par un PhaseListener qui s'éxécute avant la phase RESTORE_VIEW et que l'on déclare dans le face-config.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class SessionExpirationListener implements PhaseListener {
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
public void beforePhase(PhaseEvent event) {
// Faire quelquechose ...
}
public void afterPhase(PhaseEvent event) {
// Rien a faire ici
}
} |
Il y a un exemple ici http://solutionsfit.com/blog/2007/11...seam-security/
au aura toujours du mal à faire la différence entre un ViewState expiré et un neuf sans demander au composant qui gère les ViewStates.
On peut enfin encore mieux gérer le problème comme ici (pas encore essayé) http://in.relation.to/Bloggers/Imple...amJSFAndJQuery
En résumé, il demande au serveur confirmation de l'expiration par AJAX 3 secondes après la fin. Il désactive alors tous les liens et boutons et prévient l'utilisateur. Ce dernier peut recopier ses données (et lui dit merci dans le cas d'un long texte) mais doit re-initialiser la session.
Coté données:
Je fait implémenter l'interface javax.servlet.http.HttpSessionBindingListener à mes Beans en session et le code de valueUnbound(...) est lancé quand la session se termine.