Verifiquei o código e está igual a vídeo aula, no entanto ao clicar em logout, apresenta o erro:
HTTP Status 500 - Cannot call sendRedirect() after the response has been committed
type Exception report
message Cannot call sendRedirect() after the response has been committed
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Cannot call sendRedirect() after the response has been committed javax.faces.webapp.FacesServlet.service(FacesServlet.java:671) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) root cause
java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:488) com.sun.faces.context.ExternalContextImpl.redirect(ExternalContextImpl.java:678) com.sun.faces.application.NavigationHandlerImpl.handleNavigation(NavigationHandlerImpl.java:221) com.sun.faces.application.NavigationHandlerImpl.handleNavigation(NavigationHandlerImpl.java:183) br.com.caelum.livaria.util.Autorizador.afterPhase(Autorizador.java:32) com.sun.faces.lifecycle.Phase.handleAfterPhase(Phase.java:189) com.sun.faces.lifecycle.Phase.doPhase(Phase.java:107) com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198) javax.faces.webapp.FacesServlet.service(FacesServlet.java:658) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) note The full stack trace of the root cause is available in the Apache Tomcat/8.5.9 logs.
Classe autorizador:
package br.com.caelum.livaria.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 Autorizador implements PhaseListener{
private static final long serialVersionUID = 4983222226822177726L;
@Override
public void afterPhase(PhaseEvent event) {
FacesContext context = event.getFacesContext();
String nomePagina = context.getViewRoot().getViewId();
if("/login.xhtml".equals(nomePagina)){
return;
}
Usuario usuarioLogado = (Usuario) context.getExternalContext().getSessionMap().get("usuarioLogado");
if(usuarioLogado != null){
return;
}
NavigationHandler handler = context.getApplication().getNavigationHandler();
handler.handleNavigation(context, null, "/login?faces-redirect=true");
context.renderResponse();
}
@Override
public void beforePhase(PhaseEvent event) {
//System.out.println("FASE: " + event.getPhaseId());
}
@Override
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
}
Classe login:
package br.com.caelum.livraria.bean;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import br.com.caelum.livaria.util.RedirectView;
import br.com.caelum.livraria.dao.UsuarioDAO;
import br.com.caelum.livraria.modelo.Usuario;
@ManagedBean
@ViewScoped
public class LoginBean {
private Usuario usuario = new Usuario();
public Usuario getUsuario() {
return usuario;
}
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
public RedirectView efetuarLogin(){
System.out.println("Fazendo login do usuario " + this.usuario.getEmail());
FacesContext context = FacesContext.getCurrentInstance();
boolean existe = new UsuarioDAO().existe(this.usuario);
if(existe){
context.getExternalContext().getSessionMap().put("usuarioLogado", this.usuario);
return new RedirectView("livro");
}
return new RedirectView("login");
}
public String deslogar(){
FacesContext context = FacesContext.getCurrentInstance();
context.getExternalContext().getSessionMap().remove("usuarioLogado");
return "login?faces-redirect=true";
}
}
Em uma breve pesquisa, ocorre quando estou tentando redirecionar uma página após ter já "escrito a resposta".