Sto sviluppando un'applicazione JSF 2.0 su Glassfish v3 e sto cercando di gestire ViewExpiredException. Ma qualunque cosa faccia, ottengo sempre un rapporto di errore Glassfish al posto della mia pagina di errore.JSF: impossibile catturare ViewExpiredException
Per simulare l'occorrenza del VEE, ho inserito la seguente funzione nel mio backing bean, che attiva il VEE. Sto attivando questa funzione dalla mia pagina JSF tramite un comando link. Il Codice:
@Named
public class PersonHome {
(...)
public void throwVEE() {
throw new ViewExpiredException();
}
}
In un primo momento ho provato semplicemente aggiungendo un errore-pagina al mio web.xml:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/error.xhtml</location>
</error-page>
Ma questo non funziona, non sto reindirizzato ad errore ma sto mostrato l'ErrorPage Glassfish, che mostra un HTTP stato di 500 pagine con il seguente contenuto:
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
prossima cosa che ho provato è stato di scrivere ExceptionHandlerFactory e CustomExceptionHandler, come des citato in JavaServerFaces 2.0 - Il riferimento completo. Così ho inserito il seguente tag in faces-config.xml:
<factory>
<exception-handler-factory>
exceptions.ExceptionHandlerFactory
</exception-handler-factory>
</factory>
e ha aggiunto queste classi: La fabbrica:
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;
}
}
Il gestore di eccezioni personalizzato:
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();
}
}
ma ancora NON sono reindirizzato alla mia pagina di errore - sto ricevendo lo stesso errore HTTP 500 come sopra. Cosa sto facendo male, cosa potrebbe mancare nella mia implementazione che l'eccezione non venga gestita correttamente? Qualsiasi aiuto altamente apprezzato!
EDIT
Ok, io sono onesto. In effetti, il mio codice è in realtà scritto in Scala, ma questa è una lunga storia. ho pensato che fosse un problema di Java tutto il tempo. L'errore REALE in questo caso era la mia stessa stupidità. Nel mio codice (Scala), in CustomExceptionHandler, ho dimenticato di aggiungere la riga con "i.remove();" Pertanto, ViewExpiredException è rimasto in UnhandledExceptionsQueue dopo averlo gestito, e ha "ribollito". E quando bolle, diventa un ServletException.
Sono davvero dispiaciuto per aver confuso entrambi!
* "in modo da poter lanciare una ViewExpiredException in QUALSIASI JSF-fase" *: per impostazione predefinita, quando si esegue questa operazione all'interno di un fagiolo come nel tuo primo esempio, questo sarà avvolto in un 'FacesException' e sarà non finire nella pagina di errore prevista. – BalusC
Grazie. Hai ragione, ho rimosso la frase any-jsf-phase dalla mia ultima modifica. – ifischer
Il tuo ultimo post modificato lo ha reso funzionante? Ho bisogno di impostare lo stesso reindirizzamento sull'errore ViewExpired pure –