Problema ao enviar um PDF via Servlet

Bom dia, estou com a seguinte situação, gero um arquivo PDF e preciso disponibilizar o mesmo para que seja feito download:

response.setContentType("application/pdf");
OutputStream mout = response.getOutputStream();
String arquivo = "/Arquivo.pdf";
InputStream is = getServletContext().getResourceAsStream( arquivo );
byte b = -1;
while( (b = (byte)is.read()) > -1 ) {
	mout.write( b );
}
mout.flush(); //força o envio dos dados do buffer
mout.close();

Nessa linha ele gera a exception:

OutputStream mout = response.getOutputStream();

Exception:

java.lang.IllegalStateException: getWriter() has already been called for this response

Creio que está conflitando com o meu doPost:

public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException{ 

String action = request.getParameter("action");
response.setContentType("text/plain; charset=\"iso-8859-1\"");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
PrintWriter out = response.getWriter();
if ("exportPdf".equals(action)) this.exportPdf(request, sessao,response,msessao);

O problema que essa Servlet tem multiplas ações, será que preciso criar uma outra Servlet para conseguir fazer esse download funcionar?

no servlet ou você usa o writer ou o outputStream…
e sim, crie outra servlet para fazer o download…

Separei em uma Servlet só para isso mas agora estou com outros problemas:

Estou jogando esse pdf no Itext assim:

PdfWriter.getInstance(documento, response.getOutputStream());

Mas na hora que vou mandar para a download da nullPointer, como devo gravar esse pdf para ler dessa forma, ou como adaptar na hora descarregar ?

response.setContentType("application/pdf");
OutputStream out = response.getOutputStream();
String arquivo = "/arquivo.pdf";
InputStream is = getServletContext().getResourceAsStream( arquivo );
byte b = -1;
 while( (b = (byte)is.read()) > -1 ) {
 	out.write( b );
 }
 out.flush(); //força o envio dos dados do buffer
 out.close();

Essa linha que causa a Exception:

while( (b = (byte)is.read()) > -1 ) {

Só para entender. O seu pdf já existe? Esse erro parece indicar que você está tentando mandar um arquivo vazio (inexistente) para o browser. Esse seu código deveria ler um arquivo que existe. Pode ser que o seu caminho esteja errado e não exista o arquivo /arquivo.pdf.

Se você está criando dinamicamente, então não deve estar armazenado em lugar nenhum (ou pelo menos, você deveria encaminhar o buffer direto pra resposta). Tipo:

//.......
//criei o documento com o itext, vou fechar e mandar
//nota, baos é um java.io.ByteArrayOutputStream;
documento.close();
// setando headers da resposta
resposta.setHeader("Expires", "0");
resposta.setHeader("Pragma", "public");
// setando o content type
resposta.setContentType("application/pdf");
// setando o contentLength, precisa disso pro IEca
resposta.setContentLength(baos.size());
// escrevendo o ByteArrayOutputStream para  o ServletOutputStream
ServletOutputStream out = resposta.getOutputStream();
baos.writeTo(out);
out.flush();

abraços,

otávio

Exato não estou criando o arquivo no disco, mas ainda não funciona:

//criação do pdf aqui
PdfWriter.getInstance(documento, response.getOutputStream());
...
ByteArrayOutputStream baos = new ByteArrayOutputStream();
response.setHeader("Expires", "0");
response.setHeader("Pragma", "public");
response.setContentType("application/pdf");
response.setContentLength(baos.size());
ServletOutputStream out = response.getOutputStream();
baos.writeTo(out);
out.flush();

Era a minha aplicação que barrava, joguei em nova janela e funcionou!

Não entendi. Como vc jogou para uma nova janela?

I aí galera do fórum, tudo bem com vocês? Espero que sim.

Estou com um problema, e como encontrei neste post uma possível solução, gostaria de pedir a ajuda de vocês para corrigir o meu erro.
Meu problema consiste do seguinte, eu tenho um diretório onde estão armazenados arquivos PDFs. O meu objeto java, contém um atributo que é o caminho para este arquivo PDF. O que eu quero fazer é, a partir de um "bean", disponibilizar para o usuário o arquivo PDF para Download.

Estou utilizando o código abaixo dentro do meu Action (struts).

                        response.setContentType("application/pdf");
                                              
                        OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream());
                        String arquivo = estudo.getCaminhoArquivoLaudo();
                        
                        if ( new File(arquivo).exists() ) {                            
                            InputStream is = request.getSession().getServletContext().getResourceAsStream( arquivo );
                            byte b = -1;
                            while( (b = (byte)is.read()) > -1 ) {
                                writer.write( b );
                            }
                            
                            writer.flush(); //força o envio dos dados do buffer
                            writer.close();
                        }

no entanto, quando eu rodo o meu action, ele dá uma exception nesta linha (quando estou debugando):

while( (b = (byte)is.read()) > -1 ) {

A Exception lançada é essa:
EXCEPTION

[quote]exception

org.apache.jasper.JasperException: getOutputStream() has already been called for this response
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:510)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:387)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)[/quote]

ROOT CAUSE

[quote]root cause

java.lang.IllegalStateException: getOutputStream() has already been called for this response
org.apache.catalina.connector.Response.getWriter(Response.java:599)
org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:195)
javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:111)
org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:124)[/quote]

Alguém sabe o que eu estou fazendo de errado? Já verifiquei o caminho do arquivo e está certo, o arquivo existe. Eu verifico se o arquivo existe, ele passa, informando que existe, mais não sei o porque está acontecendo isso, de "barrar" a leitura do arquivo para disponibilizar o "download" ao usuário.

Obrigado desde já pessoal, valeu mesmo.

Abraços a todos aí.

Falows…

Júnior

Só mais uma coisa pessoal, desculpem.

O Fato do arquivo estar armazenado no meu servidor, não impede que o sistema tenha acesso a este arquivo não é?! Quero dizer, a aplicação consegue enxergar normalmente o diretório c:\Diretorio\arquivo.pdf, correto? Eu acredito que sim pelo fato de quando verifico se o arquivo existe (new File(caminho).exist) ele retorna como verdadeiro. Mas mesmo assim, eu consigo fazer a “leitura” deste arquivo???

Obrigado mais uma vez galera.

Abraços a todo aí… valeu mesmo… :wink:

fera tente fazer um link para este arquivo… acho que vc não precisa ocupar o processamento no servidor pra alguem fazer downloads.

Galera,

Sei que topico do forum já é bem antiguinho.

Mas como que eu faço para abrir o pdf em outra pagina? Aqui no meu caso esta pedindo para reenviar os dados.

Att

vcsmetallica

Pedroza… espero que vc lembre ainda da resposta, rsrs…

Mas eu to tentando fazer essa função de download e não estou conseguindo…

Eu gravo o arquivo em um diretório do servidor, e não sei como pegar de la… tem um tópico que criei, se puder me ajudar eu agradeço