Estou fazendo um trabalho da faculdade e preciso gerar um relatório de vendas por cliente. Eu gostaria que esse relatório fosse aberto em uma nova aba do navegador, eu criei um servlet para gerenciar apenas a emissão dos relatórios:
Mas ao executar o código acima eu recebo o seguinte erro:
java.lang.IllegalStateException: getWriter() has already been called for this response
org.apache.catalina.connector.Response.getOutputStream(Response.java:579)
org.apache.catalina.connector.ResponseFacade.getOutputStream(ResponseFacade.java:183)
com.farmatads.dao.svGerarRelatorioController.processRequest(svGerarRelatorioController.java:61)
com.farmatads.dao.svGerarRelatorioController.doGet(svGerarRelatorioController.java:88)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
com.farmatads.Controller.svRelatorioController.processRequest(svRelatorioController.java:60)
com.farmatads.Controller.svRelatorioController.doGet(svRelatorioController.java:118)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
Já procurei por todo o forum como resolver isso mas nada.
Agradeço desde já
pra abrir em outra aba use um target=‘blank’ no seu botao de comando ,jah este erro ai eu ja tive problemas com isso ,mas faz muito tempo e naum me lembro como resolvi isso, tente assim pra ver
OutputStream out = response.getOutputStream();
out.write(bytes);
out.flush();
java.lang.IllegalStateException: getWriter() has already been called for this response
org.apache.catalina.connector.Response.getOutputStream(Response.java:579)
org.apache.catalina.connector.ResponseFacade.getOutputStream(ResponseFacade.java:183)
com.farmatads.Controller.svGerarRelatorioController.processRequest(svGerarRelatorioController.java:62)
com.farmatads.Controller.svGerarRelatorioController.doPost(svGerarRelatorioController.java:96)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
com.farmatads.Controller.svRelatorioController.processRequest(svRelatorioController.java:60)
com.farmatads.Controller.svRelatorioController.doPost(svRelatorioController.java:131)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
Este é o problema, vc faz alguma coisa na servlet anterior que “gera o response”, quando vc dá o forward pra essa Servlet a “resposta para o usuário” já foi gerada, quando vc tenta colocar os bytes do relatório gerado no response ele lança essa excessão falando que o " getWriter() já foi chamado".
Tente chamar essa servlet diretamente, verá que ela funciona normalmente.
PS: Poste a sua servlet anterior para vermos oque podemos fazer.
Como vc me pediu deniswsrosa aqui esta a minha servlet que chama a segunda sevlet que gera o relatório. A servlet desse código eu uso para controlar o fluxo do sistema e a segunda servlet apenas para gerar o relatorio
ps: eu segui as suas dicas e consegui gerar o relatório chamando diretamente a servlet que gera o relatório a partir de um formulário em uma página JSP. Mas eu gostaria de uma servlet para controlar o fluxo da aplicação e validar os valores passados pelos formulários.
No Servlet que controla o fluxo da aplicação e chamava o servlet que gera o relatório fiz essas modificações:
// Como Estava
RequestDispatcher rd = request.getRequestDispatcher("/FarmaTads/svGerarRelatorioController?gerenciamento=notafiscal&idvenda="+idVenda);
rd.forward(request, response);
//Modifiquei para essa forma
response.sendRedirect("/FarmaTads/svGerarRelatorioController?gerenciamento=notafiscal&idvenda="+idVenda);
No servlet que gera o relatório fiz essas modificações:
// inclui essa linha
response.setHeader("Content-Disposition", "attachment; filename=NotaFiscal.pdf");
E modifiquei o método da classe gerarRelatorio dessa forma:
O navegador abre o relatório em uma nova janela ou aba, dependendo do target que você colocou no LINK ou por JS window.open().
Outra dica é que quando usar inline declare sempre o cabeçalho antes do tipo de documento senão ele se comporta como “attachment” e pede pra salvar antes de abrir o documento.