Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

O usuarioLogado continua na sessão mesmo após o TomCat ser Reiniciado

Olá,

Estou na "Aula 13 - Logout e Scopo Flash". Fiz a implementação do Logout e funcionou. Porém, identifiquei um problema que ainda não consegui resolver. Segue o passo a passo:

(1) Faço Login com o E-mail e Senha e o sistema redireciona para http://localhost:8080/livraria/livro.xhtml. O usuarioLogado é incluído na Sessão: context.getExternalContext().getSessionMap().put("usuarioLogado", this.usuario);

(2) Acesso o Eclipse e reinício o Tomcat (versão: 7.0.47). Retorno para o navegador e acesso novamente a página "http://localhost:8080/livraria/livro.xhtml". Na minha visão, como o Tomcar foi reiniciado, o sistema deveria me enviar para a página de Login, mas não é isso que está acontecendo. O sistema me direciona para a página livro.xhtml e ainda mostra o último usuário logado, ou seja, o usuário que Eu estava logado antes de reiniciar o tomcat.

Alguém poderia me ajudar? Fiz alguns procedimentos básicos: clean no projeto, clean no Tomcat, limpei todo o cache do navegador, acessei de outros navegadores: chrome, firefox, safari e o erro permanece.

Segue minhas classes "AutorizadorPhaseListener" e "LoginBean". Segue também meu cabeçalho.

package br.com.caelum.livraria.util;

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;

import br.com.caelum.livraria.modelo.Usuario;

public class AutorizadorPhaseListener implements PhaseListener {

    private static final long serialVersionUID = 1L;

    @Override
    public void afterPhase(PhaseEvent event) {

        FacesContext context = event.getFacesContext();
        String nomeDaPagina = context.getViewRoot().getViewId();

        System.out.println("[### INFORMAÇÃO ###] Nome da Página: " + nomeDaPagina);

        if ("/login.xhtml".equals(nomeDaPagina)) {
            return;
        }

        Usuario usuarioLogado = (Usuario) context.getExternalContext().getSessionMap().get("usuarioLogado");

        if (usuarioLogado != null) {
            return;
        } else {
            NavigationHandler handler = context.getApplication().getNavigationHandler();
            handler.handleNavigation(context, null, new RedirectView("login").toString());
            context.renderResponse();
        }

    }

    @Override
    public void beforePhase(PhaseEvent event) {}

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

}
package br.com.caelum.livraria.bean;

import java.io.Serializable;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import br.com.caelum.livraria.dao.UsuarioDAO;
import br.com.caelum.livraria.modelo.Usuario;
import br.com.caelum.livraria.util.RedirectView;

@ManagedBean
@ViewScoped
public class LoginBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private Usuario usuario = new Usuario();

    public Usuario getUsuario() {
        return usuario;
    }

    public RedirectView efetuarLogin() {

        System.out.println("[### INFORMAÇÃO ###] Fazendo Login do Usuário: " + this.usuario.getEmail());

        FacesContext context = FacesContext.getCurrentInstance();

        if (new UsuarioDAO().buscarPorUsuario(this.usuario)) {
            context.getExternalContext().getSessionMap().put("usuarioLogado", this.usuario);
            return new RedirectView("livro");
        } else {
            context.addMessage("efetuarLogin", new FacesMessage("Login e Senha inválidos! Favor, tente novamente!"));
            this.usuario = new Usuario();
            return null;
        }

    }

    public RedirectView efetuarLogoff() {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("usuarioLogado");
        return new RedirectView("login");
    }

}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

<h:head />

<h:body>
    <h:graphicImage library="images" name="logo.png" />

    <h:form rendered="#{usuarioLogado != null}">
        <h:outputLabel value="USUÁRIO:&nbsp;" for="usuarioLogado"/>
        <h:outputText id="usuarioLogado" value="#{sessionScope['usuarioLogado'].email.toUpperCase()}" />&nbsp;
        <h:commandButton value="Logout" action="#{loginBean.efetuarLogoff}"/>
    </h:form>

    <h1><ui:insert name="titulo"/></h1>
    <h:messages id="messages"/>
</h:body>

</html>
4 respostas
solução!

Oi Igor,

Isso realmente é um problema, pois como o servidor foi reiniciado, a sessão deveria ter sido destruida.

Mas na verdade esse comportamento é comum, pois o tomcat tem um mecanismo que faz tipo um "backup" das sessões, e as preserva mesmo após ser reiniciado.

Para desabilitar isso, você precisa editar o arquivo context.xml, que fica na pasta conf do tomcat, e descomentar essa linha:

<Manager pathname="" />

Isso deve resolver o problema.

Bons estudos!

Oi Rodrigo,

Obrigado pelo retorno! Rodrigo, fiz a configuração acima e o problema persistiu. Dei uma pesquisada e vi que precisava criar o arquivo context.xml no WebContent/META-INF. Após incluir o arquivo nesta pasta, o problema sumiu.

Abri a aplicação, fiz o login e reniciei o tomcat. Retornei para o browser e atualizei a página, a aplicação foi para a tela de login corretamente.

Gostaria de saber se realmente precisamos incluir o context.xml dentro da pasta META-INF do WebContent?

Oi Igor,

Não precisa desse arquivo não.

Talvez não tenha funcionado de primeira por conta de cache antigo do tomcat.

Teste novamente apagando esse arquivo, que deve funcionar corretamente.

Oi Rodrigo,

Realmente não precisava do arquivo. Encontrei o problema que não estava fazendo funcionar a sua solução. Na instalação do Tomcat, na configuração Server Locations, havia deixado marcado a opção "Use workspace metadata (does not modify Tomcat installation)". Com essa configuração, por padrão, o WTP gerencia todo o Tomcat para nós e não permite que configurações sejam feitas por fora do Eclipse. E era realmente isso que estava acontecendo, porque nesta configuração, o Tomcat aponta para a pasta oculta .metadata e lá dentro o arquivo conf/context.xml estava com essa linha "" comentada.

Quando você pediu para descomentar a linha "", modifiquei o arquivo context onde havia extraído os arquivos do Tomcat, só que a configuração do Server Locations não estava apontando para lá. Depois de descobrir isso, modifiquei a configuração do Server Locations para "Use Tomcat installation (takes control of Tomcat installation)". Pronto, aí tudo funcionou perfeitamente.

Rodrigo, muito obrigado pela ajuda e atenção!