2013-03-22 3 views
10

Ho esaminato molti post su questo argomento ma non sono riuscito a ottenere una soluzione che funzioni nel mio caso.Reindirizzamento dopo HttpSession timeout

Sto usando Java EE 6 con JSF 2.0 (distribuito su JBoss AS 7.1)

Nel mio web.xml ho:

<session-config> 
     <session-timeout>1</session-timeout> 
    </session-config> 

e voglio che l'utente verrà reindirizzato alla pagina di login quando la sessione scade automaticamente.

cosa ho provato:

Approccio 1: usando il filtro

Ho provato il seguente filtro:

@WebFilter() 
public class TimeOutFilter implements Filter { 

     @Override 
     public void init(FilterConfig filterConfig) throws ServletException { 
     } 

     @Override 
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, 
     ServletException { 
     System.out.println("filter called"); 
     final HttpServletRequest req = (HttpServletRequest) request; 
     final HttpSession session = req.getSession(false); 
     if (session != null && !session.isNew()) { 
      chain.doFilter(request, response); 
     } else { 
      System.out.println("Has timed out"); 
      req.getRequestDispatcher("/logon.xthml").forward(request, response); 
     } 
    } 

    @Override 
    public void destroy() { 
    } 
} 

Nel web.xml ho provato

<filter-mapping> 
    <filter-name>TimeOutFilter</filter-name> 
    <url-pattern>*.xhtml</url-pattern> 
</filter-mapping> 

e

<filter-mapping> 
    <filter-name>TimeOutFilter</filter-name> 
    <servlet-name>Faces Servlet</servlet-name> 
</filter-mapping> 

Il filtro funziona come viene chiamato su ogni richiesta (la registrazione di "Fiter chiamato" nella console). Tuttavia non viene chiamato quando la sessione scade.

Approccio 2: HttpSessionLister

ho cercato di utilizzare un HttpSessionListerner. Il metodo chiamato con la seguente firma:

public void sessionDestroyed(HttpSessionEvent se) { 
} 

Non è stato possibile reindirizzare a una pagina specifica. Quando desidero reindirizzare un utente, di solito uso lo NavigationHandler dal numero FacesContext ma in questo caso non c'è lo FacesContext (FacesContext.getCurrentInstance() restituisce null).

In base a questo post, HttpListener non può reindirizzare l'utente perché non fa parte di una richiesta.

Domanda

Qual è il modo migliore per andare a risolvere questo problema? Cosa posso fare per far funzionare uno dei due approcci sopra menzionati?

+1

Correlati: http://stackoverflow.com/q/ 4992526/1065197 –

+0

@LuiggiMendoza: Interessante, grazie. Anche se non ho mai visto il 'ViewExpiredException' e vorrei, se possibile, reindirizzare alla pagina di accesso senza che l'utente debba cliccare su nulla. – phoenix7360

+0

Per attivare il 302 sul lato server è necessaria una forma di polling sul lato client. un battito cardiaco ... –

risposta

15

Non è possibile inviare una risposta HTTP finché il client non ha inviato una richiesta HTTP. Semplice come quella. È così che funziona HTTP. Diversamente, Internet sarebbe sembrato molto diverso se qualche sito Web fosse in grado di inviare una risposta HTTP senza che il client lo richiedesse.

Un JavaScript battito cardiaco basato sulla base di attività di tastiera/mouse del cliente come come risposta here, o una meta refresh intestazione come come risposta here sarebbe la soluzione se hai fondamentalmente una sola pagina webapp (in tal modo, sei in modo efficace non utilizzando l'ambito della sessione ma l'ambito della vista), ma non funzionerà correttamente se la pagina è aperta in più schede/finestre nella stessa sessione.

Websockets è in teoria la soluzione giusta per inviare qualcosa al cliente, ma ciò richiede a sua volta una sessione attiva. Problema dell'uovo di gallina Inoltre, non funzionerebbe nei browser più vecchi attualmente ancora relativamente largamente in uso, quindi dovrebbe attualmente essere semplicemente usato per il miglioramento progressivo.

La soluzione migliore è definire una pagina di errore che si riferisce al caso in cui l'utente finale richiama un'azione mentre la sessione è scaduta. Vedi anche javax.faces.application.ViewExpiredException: View could not be restored.

+1

Ora vedo il mio fraintendimento. Piuttosto che reindirizzare automaticamente l'utente, ho bisogno di qualcosa che permetta all'utente di sapere se esegue un'azione dopo che la sessione è scaduta. – phoenix7360

-1

Capisco che stiate usando java-EE6 e JSF, ma se poteste provare a usare il codice JSP o convertire questo codice qui sotto per lavorare in un servlet. Supponendo che si stia utilizzando il nome utente per verificare la sessione, dopo aver impostato il timeout della sessione nel file web.xml. Si noti che il codice JSP e il codice servlet sono simili. Il codice per la convalida della sessione potrebbe essere simile a questo. (Formato JSP) Se il nome utente funge da chiave principale nel database.

<% 
    String un = (String)session.getAttribute("un"); 

    if(un == null){ 
    response.sendRedirect(login page); 
    return; 
}else{ 
     code to process login form 
} 
    %> 

codice Servlet potrebbe essere la seguente

String un = (String)session.getAttribute("un"); 
if(un == null){ 
    response.sendRedirect(loginPage); 
} 
0

In HttpSessionListerner non è possibile inviare una risposta a utente. Un buon modo per ottenere questo risultato è con il polling, il browser invia richieste HTTP a intervalli regolari e riceve immediatamente una risposta.
Ci sono molti modi per farlo:

  1. È possibile utilizzare Plain Old javascript per il polling: Questo funzionerà in ambiente cross browser.

    funzione refresh() {

    // make Ajax call here, inside the callback call: 
    
    setTimeout(refresh, 5000); 
    
    // ... 
    

    }

    // initial call, or just call refresh directly 
    

    setTimeout (refresh, 5000);

  2. È possibile utilizzare Web Sockets. specifica presa Web è presente sui link qui sotto:

    http://dev.w3.org/html5/websockets/

-1

È possibile utilizzare un filtro e fare il seguente test:

HttpSession session = request.getSession(false); 
if(session != null && !session.isNew()) { 
    chain.doFilter(request, response); 
} 
else {enter code here 
    response.sendRedirect("/login.jsp"); 
} 
Problemi correlati