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

Erro 500 ao clicar em logout.

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".

3 respostas

Oi Fabricio, olhando o código eu vou confessar, ainda não vi o erro.. de todo modo, a descrição do problema que vc achou na net está correto.. vc já escreveu o cabeçalho do response, e agora quer escrever de novo. Minha sugestão: coloca uns breakpoints(pode ser syso tb :)) no bean de login e no phaselistener para ver se tem alguma parte sendo chamada mais de uma vez.

solução!

Acabei acatando a solução de outro usuário que ocorreu a mesma coisa, tirando o return "login?faces-redirect=true" do método deslogar.

Fabrício, tive o mesmo problema, quando eu abria o navegador sem nunca ter subido o contexto e ja ia direto para alguma pagina tipo livro.xhtml e rodei javadocs por ai e foruns, mas nada faz voltar um "response commited", ai a unica solução que encontrei foi colocar uma configuração no web.xml para quando der esta exception redirecionar para o login.xhtml.

<error-page>
        <exception-type>java.lang.IllegalStateException</exception-type>
        <location>/login.xhtml</location>
    </error-page>

espero que te ajude.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software