[Resolvido] PhaseListener + problemas com sessão expirada, alguem sabe como resolver?

Olá pessoal, boa noite.
Estou com um problema na minha classe que implementa o PhaseListener, onde após a autenticação no sistema
e deixar o mesmo sem utilização durante o tempo definido no web.xml, recebo a mensagem que a view não pôde ser restaurada. Contudo era para o sistema
me redirecionar para a página de login, ou uma outra página especificada, informando que a sessão expirou para entrar com os dados do usuário novamente.

Tenho a seguinte classe abaixo:


package br.com.notaroberto.control;

import br.com.notaroberto.model.Usuario;
import javax.el.ELResolver;
import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

/**
 * 
 * @author Lessandro
 */
public class FaseListener implements PhaseListener {

    private static final long serialVersionUID = 1L;
    private static final String paginaLogin = "login.xhtml";
    private static final String paginaLoginRedirecionada = "/login?faces-redirect=true";
    private static final String paginaIndexRedirecionada = "/index?faces-redirect=true";
    private boolean sessaoExpirou, ehPaginaLogin;

    public FaseListener() {
    }

    @Override
    public void afterPhase(PhaseEvent event) {

        if (event.getPhaseId().equals(PhaseId.RENDER_RESPONSE)) {
            try {
                FacesContext fc = event.getFacesContext();
                if (fc.getViewRoot() == null) {
                    sessaoExpirou = true;
                } else {
                    ehPaginaLogin = fc.getViewRoot().getViewId().contains(paginaLogin);
                }

                ELResolver elr = fc.getApplication().getELResolver();
                Usuario usuarioAutenticado = (Usuario) elr.getValue(fc.getELContext(), null, "usuarioAutenticado");
                NavigationHandler nav = fc.getApplication().getNavigationHandler();

                if (!sessaoExpirou && !ehPaginaLogin && usuarioAutenticado == null) {
                    nav.handleNavigation(fc, null, paginaLoginRedirecionada);
                } else if (!sessaoExpirou && ehPaginaLogin && usuarioAutenticado != null) {
                    nav.handleNavigation(fc, null, paginaIndexRedirecionada);
                }
            } catch (Exception e) {
                System.out.println("Erro: " + e);
            }
        }
        System.out.println("AFTER: " + event.getPhaseId());
    }

    @Override
    public void beforePhase(PhaseEvent event) {
        /*if (event.getPhaseId().equals(PhaseId.RESTORE_VIEW)) {
        try {
        FacesContext fc = event.getFacesContext();
        if (fc.getViewRoot() == null) {
        sessaoExpirou = true;
        }
        if (sessaoExpirou) {
        NavigationHandler nav = fc.getApplication().getNavigationHandler();
        nav.handleNavigation(fc, null, paginaLoginRedirecionada);
        }
        } catch (Exception e) {
        System.out.println("Erro: " + e);
        }
        }*/
        System.out.println("BEFORE: " + event.getPhaseId());
    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.ANY_PHASE;
    }
}

Se eu descomentar o código da fase beforePhase, o sistema entra num loop infinito, devido à fase de visão o viewRoot() do contexto da aplicação estar sempre nulo,
e devido á isso ficar chamando a página de login.xhtml.
Alguém sabe como implementar algo que resolvesse essa questão, como descrita anteriormente?
Já segui diversos tutoriais que basicamente possuem o mesmo código que eu postei, porém essa questão de sessão expirada não é tratada, apenas autenticação do
usuário recuperando o escopo trazido do managedBean que realiza o processo de carregar o usuário da base.
Agradeço desde já pela atenção,
Att,
Lessandro

Segue a mensagem de erro:

javax.faces.application.ViewExpiredException: viewId:/index.xhtml - A exibição de /index.xhtml não pôde ser restaurada.
	at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:212)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:110)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
	at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
	at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:332)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:233)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
	at java.lang.Thread.run(Thread.java:619)

O método de autenticação no web.xml

    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>server</param-value>
    </context-param>

E a configuração do tempo de sessão:

    <session-config>
        <session-timeout>5</session-timeout>
    </session-config>

Abs,
Lessandro

Eh, alguém?
Será que ng que tenha desenvolvido uma aplicação web tenha passado por isso?
Ou tenha colocado o tempo maior apenas para “burlar” essa questão?
Abs,
Lessandro

Tentei implementar o método beforePhase de maneira diferente, seguindo alguns tutoriais existentes na internet, mas o problema que a view da página index.xhtml não pôde ser restaurada continua acontecendo.
Segue o código abaixo:

    @Override
    public void beforePhase(PhaseEvent event) {
        if (event.getPhaseId().equals(PhaseId.RESTORE_VIEW)) {
            try {
                ExternalContext context = event.getFacesContext().getExternalContext();
                HttpServletRequest request = (HttpServletRequest) context.getRequest();
                if (!request.getRequestURL().toString().contains(paginaLogin) && context.getSession(false) == null) {
                    context.redirect(request.getContextPath() + paginaLogin); //Ao tentar efetuar a troca da página index.xhtml para a página login.xhtml ele não consegue realizar, 
                    // exibindo o erro: viewId:/index.xhtml - A exibição de /index.xhtml não pôde ser restaurada.
                }
            } catch (Exception e) {
                //Nao imprime nada
            }
        }
    }

conseguiu resolver ?
tb estou com o mesmo problema

Sim, consegui…
Depois dê uma olhada lá no meu Blog que trato sobre esse assunto.


Abs,
Lessandro