0

I am trying to display a save as dialog box to save a PDF file. This should happen on click of a link in the JSP. On click of this link I call a struts action which prepares PDF and forwards to another JSP 'download.jsp' which I want to use for the download box.

I tried using 'document.execCommand' but it seems this only works for .txt and .html files.

Then I tried doing it by setting response headers and the content type. Following is the code in my download.jsp. But this writes junk characters to my browser.

Please let me know a solution for this problem.

<%@ page language="java"     import="javax.servlet.ServletOutputStream,java.io.BufferedOutputStream,java.io.DataInputStr eam,java.io.File,java.io.FileInputStream"%><%

response.setHeader("Content-Disposition","attachment;filename=\"" + "mandateOut.pdf" + "\"");
response.setContentType( "application/pdf" );

response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "max-age=0");   
File file = new File(<fully qualified file name>);
response.setContentLength( (int)file.length() );

// get the OutputStream and buffer our bytes to it
ServletOutputStream outStream = response.getOutputStream();

byte[] buf = new byte[1024];
DataInputStream in = new DataInputStream(new FileInputStream(file));

int len;
while ((in != null) && ((len = in.read(buf)) != -1))
{
outStream.write(buf,0,len);
}

// keep the page from freaking out over our use of it's outputstream
in.close();
outStream.flush();
outStream.close();

%>
Bobrovsky
  • 13,789
  • 19
  • 80
  • 130
Kalo
  • 1
  • 2
  • In addition to JB Nizet's answer you may need `response.setContentType("application/x-download")` to get the browser to show a download dialog (rather than displaying the PDF directly in the browser) – Martin Wilson Apr 07 '13 at 08:09
  • @MartinWilson: I disagree. The content type is PDF. The browser will display a download dialog thanks to the Content-Disposition=attachment header. – JB Nizet Apr 07 '13 at 08:16
  • Have you seen this work in all browsers, including IE? – Martin Wilson Apr 07 '13 at 08:35
  • Just reading up on this, it looks like you're right. I do remember having problems getting files to download reliably without setting the content type to x-download but that was a few years ago. – Martin Wilson Apr 07 '13 at 08:42
  • Maybe I read this all those years ago (this is from a book published in 2002): http://www.onjava.com/pub/a/onjava/excerpt/jebp_3/index3.html – Martin Wilson Apr 07 '13 at 09:58

1 Answers1

1

You're using Struts, an MVC framework. In such a framework, the View, whose role is to generate HTML markup, is implemented as a JSP. It should only contain HTML, JSP EL, and JSP tags. No Java code. And its default content type is text/html.

The controller's role is to handle presentation logic, and is implemented using Java actions.

In this case, you don't have any HTML markup to generate. You only need to send bytes to the response output stream. So why are you using a JSP to do that? It's not its job. You should do that directly from the controller (i.e. the action).

Put the code above directly in the action, and everything should be fine.

Note that :

  • you don't need a DataInputStream to read bytes. You should prefer a BufferedInputStream instead.
  • this stream should be closed in a finally block.
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Thanks JB Nizet! The solution worked. The dialog box is now displayed. But once I save the PDF and try to open it I get an error that says.. the file has been damaged. I am converting the PDF in byte[] and keeping this in the session. On click of a link on the JSP DownloadAction is called which reads the byte[] form session and executes the above logic. – Kalo Apr 09 '13 at 17:13