Problemas com Servlet - Cannot forward after response has been committed [Resolvido]

4 respostas
G

Olá pessoal!
Pesquisei aqui no fórum a respeito deste erro e vi relatos de que se trata de resposta da Servlet e requisições para ela, só não sei onde corrigi-la para que funcione corretamente, por enquanto só consigo inserir dados, mas não consigo alterar e excluir, pois a estrutura montada com try-catch não serve para isto.

O Log do Tomcat é este:

30/11/2009 00:09:24 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet ControlePdt threw exception
java.lang.IllegalStateException: Cannot forward after response has been committed
        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:312)
        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
        at controle.ControlePdt.processRequest(ControlePdt.java:134)
        at controle.ControlePdt.doPost(ControlePdt.java:229)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:390)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
        at java.lang.Thread.run(Thread.java:619)

E a servlet é esta:

package controle;

import DAO.ProdutoDAO;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import modelo.Produto;

/**
 *
 * @author guevara
 */
public class ControlePdt extends HttpServlet {
   
    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
         /* Instancia objeto de ProdutoDao */
      ProdutoDAO produtoDAO = new ProdutoDAO();

      /* Instancia objeto de modelo de Produto */
      Produto produto = new Produto();

      /* Cria objeto despachante de requisição */
      RequestDispatcher rd = null;

      /*================================================================
       * Primeira parte: executa o método validar, através de uma estru-
       * tura "try-catch-finally", para verfificar se os dados enviados
       * estão corretos. Se estiver tudo OK (validar retornou "true",
       * executa o if do try. Caso contrário, executa o catch, cria
       * ojeto com mensagem de erro e executa de novo a view que chamou
       * esta classe controladora.
       =================================================================*/

      try {
          
        if ( validar( request )) {

            //produto.setCodigo(Integer.parseInt(request.getParameter("codigo")));

            produto.setDescricao(request.getParameter("descricao"));

            produto.setQuantidade(Integer.parseInt(
            request.getParameter("quantidade")));

            produto.setEstoque(Integer.parseInt(request.getParameter("estoque")));

            /* Só coloca valor em codigo se for alteraçào ou
               exclusão */
            if ( request.getParameter("codigo") != null )
                produto.setCodigo(Integer.parseInt(
                      request.getParameter("codigo")));
          }

      } catch ( ExcecaoOblivion ex) {
        /* Se entrou no catch, algum erro aconteceu (ver método
          validar ao final desta classe). A seguir, é criado o
          objeto "erro", contendo a exceção lançada no método validar. */
        request.setAttribute( "erro", ex);

        /* Verifica qual formulário acionou esta classe, e o executa de
           novo, desta vez enviando a mensagem de erro */
        if ( request.getParameter("cmd").equals("inc")) {
           rd = request.getRequestDispatcher("/incProduto.jsp");
        }
        else if ( request.getParameter("cmd").equals("alt")) {
           rd = request.getRequestDispatcher("/altProduto.jsp");
        }
        else if ( request.getParameter("cmd").equals("exc")) 
           rd = request.getRequestDispatcher("/excProduto.jsp");
        

        /* Executa o formulário definido nos ifs acima */
        rd.forward( request , response);

      }

    /*===============================================================
     * Segunda parte: se chegar aqui, significa que nenhum erro
     * foi encontrado pelo método validar. Então, o programa verifica
     * qual a ação que deve ser executada (inclusão, alteração ou
     * exclusão), testando o campo invisível de formulário enviado
     * (cmd).
     ================================================================*/

     if ( request.getParameter("cmd").equals("inc")) {
         /*
          * try-catch-finally de INCLUSÃO (usando método incluir
          * do objeto produtoDAO).
         */
         rd = request.getRequestDispatcher("/incProduto.jsp");
         try {
            produtoDAO.incluir(produto);
            Mensagem mens = new Mensagem();
            mens.setMensagem("Inclusão realizada com sucesso!");
            request.setAttribute( "msg" , mens );
         
         } catch (ExcecaoOblivion ex) {
            request.setAttribute("erro" , ex );
         }
     
         finally {
           rd.forward( request , response);
         }
     }


     if ( request.getParameter("cmd").equals("alt")) {
        /*
         * try-catch-finally de ALTERAÇÃO (usando método alterar
         * do objeto produtoDAO).
        */
        
        rd = request.getRequestDispatcher("/altProduto.jsp");
        try {
            produtoDAO.alterar(produto);
            Mensagem mens = new Mensagem();
            mens.setMensagem("Alteração realizada com sucesso!");
            request.setAttribute( "msg" , mens );
        }
        catch (ExcecaoOblivion ex)  {
            request.setAttribute("erro" , ex );
        }
        finally {

          rd.forward( request , response);
          
        }
     }

     if ( request.getParameter("cmd").equals("exc")) {
        /*
         * try-catch-finally de EXCLUSÃO (usando método excluir
         * do objeto produtoDAO).
        */
        rd = request.getRequestDispatcher("/excProduto.jsp");
        try {
            produtoDAO.excluir(produto);
            Mensagem mens = new Mensagem();
            mens.setMensagem("Exclusão realizada com sucesso!");
            request.setAttribute( "msg" , mens );
        }
        catch (ExcecaoOblivion ex)  {
            request.setAttribute("erro" , ex );
        }
        finally {
            rd.forward( request , response);
        }
     }

     /* Fim do método processRequest */

    }
    
    private boolean validar( HttpServletRequest request )
        throws ExcecaoOblivion {

    /*===================================================================
     * Este método verifica se houve algum erro nos dados enviados para
     * a classe controladora. Toda classe controladora terá este método.
     * Cada campo deve ser testado na ordem em que aparece na view. Alguns
     * campos podem ter mais de um teste (ver cargaHoraria e numPeriodos).
     * Se nenhum erro acontecer, o método retorna "true". Em caso de erro,
     * uma exceção do tipo "excecaoOblivion" é lançada.
     * ATENÇÃO: este método é chamado pelo "try-catch-finally" do método
     * processRequest desta classe (ver acima).
     ====================================================================*/
   if ( request.getParameter("descricao").length() == 0 )
        throw new ExcecaoOblivion("Descrição de Curso não pode ficar em branco",0);

    try {
        Integer.parseInt(request.getParameter("quantidade"));
    }
    catch (NumberFormatException ex){
        throw new
        ExcecaoOblivion("Quantidade só pode receber valores númericos",1);
    }

    if ( Integer.parseInt( request.getParameter("quantidade")) < 0)
        throw new
        ExcecaoOblivion("Quantidade deve ser maior que 0",1);


    try {
        Integer.parseInt(request.getParameter("estoque"));
    }
    catch (NumberFormatException ex){
        throw new
        ExcecaoOblivion("Estoque só pode receber valores númericos",2);
    }

    if ( Integer.parseInt( request.getParameter("estoque")) < 0)
        throw new
        ExcecaoOblivion("Estoque deve ser maior que 0",2);

    return true;
}

    // <editor-fold defaultstate="collapsed" desc="Métodos HttpServlet. Clique no sinal de + à esquerda para editar o código.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
        
    } 

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
  
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
       
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */

    public String getServletInfo() {
        return "Servlet Controle de Produtos";
    }// </editor-fold>

}

Para poder inserir eu coloquei type=“submit” no e funcionou, mas não consigo alterar e exluir os dados.

Obrigado desde já pela ajuda.

Abraço!

4 Respostas

G

Tambem estou com o mesmo problema, usei try catch na servlet e não sei como editar para que faça um forward.

G

A idéia eu até entendi, o Servlet responde uma requisição e ela não fecha (commita), ai ele não responde mais.
Já li várias respostas para esse tipo de problema, mas não vi nenhum código que pudesse adaptar ao meu para resolver a questão. Talvez seja um detahe bobo, mas que ainda não percebi no meu código.

G

Alguém ajuda ae, tô com o mesmo problema.
Tô editando direto o servlet e a droga não funciona, eu clico nos botões e nada acontece…

G

Voltei para postar a solução do problema, obtive resposta numa comunidade no Orkut.

Primeiramente o que estava errado era o javascript, o action SEMPRE será a servlet, no meu estava apontando para as JSPs alterar e excluir, portanto o correto é isto:

function atualizar( codigo,
                    descricao,
                    quantidade,
                    estoque,
                    cmd){
 document.form1.codigo.value = codigo;
 document.form1.descricao.value = descricao;
 document.form1.quantidade.value = quantidade;
 document.form1.estoque.value = estoque;
 document.form1.cmd.value = cmd;
/* Decide qual JSP será executado */
if ( cmd == "alt")
     document.form1.action = 'ControlePdt';
 else
     document.form1.action = "ControlePdt";

/* Envia o formulário e executa a ação escolhida */

 document.form1.submit();

}

function sucesso() {
alert("Dados incluídos com sucesso!");
}

Segundo, na tag do form lá nas JSPs não consta a id, pois no botão o existe submit através do método document.getElementById, logo, a tag ficará assim:

<form name="form1" method="post" action="ControlePdt" id="form1">

Coloquei na id “form1” mesmo, poderia ter colocado qualquer coisa, tipo, “alt” para a página JSP de alterar e “exc” para a página JSP de exclusão. Tentei pelo método document.getElementByName, mas não deu certo, poderia ter pego com o nome do form.

Essa é a solução do problema.

Abraço!

Criado 30 de novembro de 2009
Ultima resposta 9 de dez. de 2009
Respostas 4
Participantes 2