[JSF/Ajax] Le chiamate Ajax in situazioni di session timeout

Faces-2.0-JSF-AjaxChi lavora con JSF (Java Server Faces)  e sfrutta i meccanismi di AJAX, sicuramente si è imbattuto nel problema delle richieste asincrone “parziali” (partial ajax) effettuate quando la sessione utente è andata in timeout. Come è ovvio in tale situazione, le richieste non vanno a buon fine, ma poiché non vi è un “refresh” di tutta la pagina (ma solo di sue porzioni precise), le risposte non vengono propriamente trattate come tali lato client e non “ci si accorge” del session timeout, rimanendo “piantati” sulla stessa pagina senza veder accadere nulla (nemmeno sui log applicativi viene stampato nulla)  

Si potrebbe pensare di effettuare una redirect ad una pagina di login, chiedendo all’utente di riloggarsi. A tale scopo, tra i tanti metodi che si trovano online (WebFilter, Interceptorecc.), propongo qui quello che utilizza un PhaseListener, che si interpone tra tutte le richieste HTTP effettuate (siano essere normali request o, appunto, partial ajax request), in modo da controllare se la sessione è valida e, in caso negativo, rimandare l’utente su una pagina definita.

Ecco la classe che occorre inserire nel vostro progetto JSF:

/* Classe SessionExpirationPhaseListener */

import javax.faces.application.ConfigurableNavigationHandler;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.servlet.http.HttpServletRequest;

/**
 * 
 * listener per il controllo della session timeout per le chiamate AJAX
 *
 */
public class SessionExpirationPhaseListener implements PhaseListener {

    /**
	 * 
	 */
	private static final long serialVersionUID = 257760346127143382L;

	@Override

    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }

    @Override
    public void beforePhase(PhaseEvent event) {

    }

    @Override
    public void afterPhase(PhaseEvent event) {

        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest httpRequest = (HttpServletRequest) context.getExternalContext().getRequest();

        if (httpRequest.getRequestedSessionId() != null && !httpRequest.isRequestedSessionIdValid()) {
            String facesRequestHeader = httpRequest.getHeader("Faces-Request");
            boolean isAjaxRequest = facesRequestHeader != null && facesRequestHeader.equals("partial/ajax");

            if (isAjaxRequest) {
                ConfigurableNavigationHandler handler = (ConfigurableNavigationHandler) context.getApplication().getNavigationHandler();
                handler.performNavigation("session-expired");
            }
        }
    }
}

 

Occorre poi inserire il seguente mapping nel file faces-config.xml :

<lifecycle>
    <phase-listener>it.francescoficetola.web.filter.SessionExpirationPhaseListener</phase-listener>
</lifecycle>

Così facendo tutte le richieste HTTP, comprese quelle di tipo partial/ajax, verranno intercettate dal listener.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *


8 + = quattordici