JSF: Ne peut pas attraper ViewExpiredException
Je suis l'élaboration d'un programme JSF 2.0 de l'application sur Glassfish v3 et je suis en train de gérer la ViewExpiredException. Mais quoi que je fasse, j'ai toujours été un Glassfish rapport d'erreur à la place de ma propre page d'erreur.
Pour simuler l'apparition de la VEE, j'ai inséré la fonction suivante dans mon backing bean, qui déclenche la VÉ. Je suis le déclenchement de cette fonction à partir de mon JSF page par le biais d'un commandLink.
Le Code:
@Named
public class PersonHome {
(...)
public void throwVEE() {
throw new ViewExpiredException();
}
}
Au début, j'ai essayé en ajoutant simplement une erreur de la page à mes web.xml:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/error.xhtml</location>
</error-page>
Mais cela ne fonctionne pas, je ne suis pas redirigé vers l'erreur, mais je me suis montré Glassfish errorpage, qui montre un État HTTP de 500 pages avec le contenu suivant:
description:The server encountered an internal error () that prevented it from fulfilling this request.
exception: javax.servlet.ServletException: javax.faces.application.ViewExpiredException
root cause: javax.faces.el.EvaluationException:javax.faces.application.ViewExpiredException
root cause:javax.faces.application.ViewExpiredException
Prochaine chose que j'ai essayé était d'écrire ExceptionHandlerFactory et un CustomExceptionHandler, comme décrit dans JavaServerFaces 2.0 - La Référence Complète. J'ai donc inséré la balise suivante dans faces-config.xml:
<factory>
<exception-handler-factory>
exceptions.ExceptionHandlerFactory
</exception-handler-factory>
</factory>
Et ajouté ces classes:
Le réglage d'usine:
package exceptions;
import javax.faces.context.ExceptionHandler;
public class ExceptionHandlerFactory extends javax.faces.context.ExceptionHandlerFactory {
private javax.faces.context.ExceptionHandlerFactory parent;
public ExceptionHandlerFactory(javax.faces.context.ExceptionHandlerFactory parent) {
this.parent = parent;
}
@Override
public ExceptionHandler getExceptionHandler() {
ExceptionHandler result = parent.getExceptionHandler();
result = new CustomExceptionHandler(result);
return result;
}
}
La coutume gestionnaire d'exception:
package exceptions;
import java.util.Iterator;
import javax.faces.FacesException;
import javax.faces.application.NavigationHandler;
import javax.faces.application.ViewExpiredException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;
class CustomExceptionHandler extends ExceptionHandlerWrapper {
private ExceptionHandler parent;
public CustomExceptionHandler(ExceptionHandler parent) {
this.parent = parent;
}
@Override
public ExceptionHandler getWrapped() {
return this.parent;
}
@Override
public void handle() throws FacesException {
for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
ExceptionQueuedEvent event = i.next();
System.out.println("Iterating over ExceptionQueuedEvents. Current:" + event.toString());
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
Throwable t = context.getException();
if (t instanceof ViewExpiredException) {
ViewExpiredException vee = (ViewExpiredException) t;
FacesContext fc = FacesContext.getCurrentInstance();
NavigationHandler nav =
fc.getApplication().getNavigationHandler();
try {
//Push some useful stuff to the flash scope for
//use in the page
fc.getExternalContext().getFlash().put("expiredViewId", vee.getViewId());
nav.handleNavigation(fc, null, "/login?faces-redirect=true");
fc.renderResponse();
} finally {
i.remove();
}
}
}
//At this point, the queue will not contain any ViewExpiredEvents.
//Therefore, let the parent handle them.
getWrapped().handle();
}
}
Mais ENCORE, je ne suis PAS redirigé vers ma page d'erreur que j'obtiens la même erreur HTTP 500, comme ci-dessus.
Ce que je fais mal, ce qui est peut-être manquant dans ma mise en œuvre de cette exception n'est pas gérée correctement? Tout aide très appréciée!
MODIFIER
Ok, je suis honnête. En fait, mon code est écrit en Scala, mais c'est une longue histoire. je pensais que c'était un Java problème tout le temps.
La VÉRITABLE erreur dans ce cas était mon propre ahurissant. Dans mon (Scala) du code, dans CustomExceptionHandler, j'ai oublié d'ajouter la ligne avec le "je.remove();" de Sorte que le ViewExpiredException resté dans la UnhandledExceptionsQueue après la manipulation, et il "propagée".
Et quand il les bulles, il devient un ServletException.
Je suis vraiment désolé pour la confusion à vous deux!
FacesException
et qu'il ne finira pas jusqu'à la page d'erreur.Merci. Vous avez raison, j'ai enlevé le tout-jsf-la phase de déclaration de la part de mon dernier montage.
Est-ce que votre dernier post édité le faire fonctionner ? J'ai besoin de la même redirection sur ViewExpired erreur ainsi
OriginalL'auteur ifischer | 2010-06-05
Vous devez vous connecter pour publier un commentaire.
Ce cas test est faux. Le
ViewExpiredException
est généralement jeté pendant la restauration de la vue (car il manque dans la session), et non pas lors du rendu de la réponse, ni de l'instanciation de la fève. Dans votre cas, cette exception est levée lors de l'instanciation de la fève et de cette exception est été enveloppé dans unServletException
.La réel
ViewExpiredException
est généralement jetés lorsque vous envoyez une requête HTTP POST pour le serveur, le temps de la session HTTP est expiré. Donc, il y a fondamentalement deux manières de reproduire cette manière fiable:Ouvrir un JSF page avec un formulaire POST (
h:form
est par défaut déjà en POSTE) dans un webbrowser, pour arrêter le serveur et nettoyer son répertoire de travail (important, car la plupart des serveurs sérialiser d'ouvrir des sessions sur le disque lors de l'arrêt et unserialize sur le démarrage), redémarrez le serveur et de le soumettre à la déjà ouverte. UnViewExpiredException
sera levée.Définir la
<session-timeout>
dansweb.xml
à1
minutes et soumettre le formulaire de plus de 1 minute après l'ouverture de la JSF page avec le formulaire de publication. Ceci lancera leViewExpiredException
.Parce qu'un
ServletException
est jeté.OriginalL'auteur BalusC
Je ne suis pas un expert. Ce sont juste des suppositions sauvages ou des suggestions.
1) Essayez de les rediriger vers une page HTML standard pour voir si cela fonctionne
2) Sur cette base , il devrait fonctionner avec la première approche elle-même, essayer d'écrire un JSF PhaseListener et de lancer la même exception à la VUE de RESTAURATION de la Phase.Maintenant, vous jettent soit dans l'INVOQUER l'APPLICATION ou de la mise à JOUR du MODÈLE de Phase.
3) Par un sysout , assurez-vous que la page d'erreur est configuré à l'aide de Servlet Contexte (je n'ai pas essayé mais Ça devrait être possible)
Même je suis curieux de ce que pourrait être le problème est!!!
Hmm non c'est pas la phase de pourquoi ça ne marchait pas, j'ai également obtenir le Statut de 500 lorsque je lance l'exception dans le RESTORE_VIEW-phase (un temps, il a travaillé, mais pas plus) Ont pour approfondir...
OriginalL'auteur gekrish