Quando in JSF la sessione scade si incappa nella tipica eccezione di tipo
javax.faces.application.ViewExpiredException
Questo errore si verifica quando l'utente richiede una pagina ma la sessione è ormai scaduta, per cui non si riesce a ricostruire l'alberatura degli oggetti propria di JSF.
Un modo molto semplice per ovviare a questa eccezione è quello di dichiararla nel web.xml in questo modo:
Il problema di questo approccio è che non gestisce i casi di chiamate ajax, ed essendo ormai il supporto di ajax il comportamento base di tutti i componenti di JSF 2.0 la dichiarazione nel web.xml non basta.
E' necessario quindi creare una classe che estenda
javax.faces.context.ExceptionHandlerWrapper
in questo modo
javax.faces.context.ExceptionHandlerFactory e che faccia l'override del metodo getExceptionHandler tornando il nostro Handler personalizzato che gestisce la ViewExpiredException.
Quindi nel faces-config.xml dobbiamo dichiarare questa factory in questo modo:
javax.faces.application.ViewExpiredException
Questo errore si verifica quando l'utente richiede una pagina ma la sessione è ormai scaduta, per cui non si riesce a ricostruire l'alberatura degli oggetti propria di JSF.
Un modo molto semplice per ovviare a questa eccezione è quello di dichiararla nel web.xml in questo modo:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/viewExpired.xhtml</location>
</error-page>
Il problema di questo approccio è che non gestisce i casi di chiamate ajax, ed essendo ormai il supporto di ajax il comportamento base di tutti i componenti di JSF 2.0 la dichiarazione nel web.xml non basta.
E' necessario quindi creare una classe che estenda
javax.faces.context.ExceptionHandlerWrapper
in questo modo
package it.exceptionHandler;
import it.util.Costanti;
import it.util.Utility;
import java.io.IOException;
import java.util.Iterator;
import javax.faces.FacesException;
import javax.faces.application.ViewExpiredException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import org.apache.log4j.Logger;
public class ViexExpiredExceptionHandler extends ExceptionHandlerWrapper {
private static final Logger log=Logger.getLogger(Costanti.LOGGER);
private ExceptionHandler parent;
public ViexExpiredExceptionHandler(ExceptionHandler parent){
this.parent=parent;
}
@Override
public ExceptionHandler getWrapped() {
return this.parent;
}
@Override
public void handle() throws FacesException{
FacesContext facesContext = FacesContext.getCurrentInstance();
for (Iterator<ExceptionQueuedEvent> iter = getUnhandledExceptionQueuedEvents().iterator(); iter.hasNext();) {
Throwable exception = iter.next().getContext().getException();
if (exception instanceof ViewExpiredException) {
final ExternalContext externalContext = facesContext
.getExternalContext();
try {
facesContext.setViewRoot(facesContext.getApplication()
.getViewHandler()
.createView(facesContext, "/viewExpired.jsf"));
externalContext.redirect("viewExpired.jsf");
facesContext.getPartialViewContext().setRenderAll(true);
facesContext.renderResponse();
}
catch(IOException ioex){
log.error(Utility.stackToString(ioex));
}
finally {
iter.remove();
}
}
}
getWrapped().handle();
}
}
Quindi occorre creare una classe che estendajavax.faces.context.ExceptionHandlerFactory e che faccia l'override del metodo getExceptionHandler tornando il nostro Handler personalizzato che gestisce la ViewExpiredException.
package it.exceptionHandler;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerFactory;
public class MyExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory parent;
public MyExceptionHandlerFactory(ExceptionHandlerFactory parent){
this.parent=parent;
}
@Override
public ExceptionHandler getExceptionHandler() {
ExceptionHandler result=parent.getExceptionHandler();
result=new ViexExpiredExceptionHandler(result);
return result;
}
}
Quindi nel faces-config.xml dobbiamo dichiarare questa factory in questo modo:
<factory>
<exception-handler-factory>it.exceptionHandler.MyExceptionHandlerFactory</exception-handler-factory>
</factory>
Nessun commento:
Posta un commento