jGuru
Register Email     Password Forgot your
password?
HOME FAQS FORUMS DOWNLOADS ARTICLES PEERSCOPE LEARN

  Search   jGuru Search Help

Question How do I download a (binary, text, executable) file from a servlet or JSP?
Topics Java:API:JSP, JavaScript, Java:API:Servlets:Files:Downloading
Author Alex Chaffee PREMIUM
Created Feb 1, 2000 Modified Nov 2, 2001


Answer

Solution 1: Just use HTTP! This has nothing to do with servlets per se. Make sure the file is on your web server. Then you can either embed a link for your user to click, as

<a href="runme.exe">Click here to download the Runme app</a>
or have your servlet or JSP send a redirect to the file, as
response.sendRedirect("http://myserver.com/files/runme.exe");
or get fancy with JavaScript (see this FAQ for inspiration).

The point is -- this is still the World Wide Web! HTTP is a file transfer protocol; downloading files what it's for!

Solution 2: Open the file from your servlet using java.io classes, and shove the bytes down the response stream. Make sure to set the content type to match the type of file, e.g. response.setContentType("image/gif") or response.setContentType("application/x-msword"). This technique is a little more expensive, but allows you to do things like security checks, or to access files that are on your web server host, but outside the HTTP directory structure.

For source code to a servlet that "downloads" (actually it's uploading, and the client is downloading, right?) a text file, see this FAQ answer.

Another way to look at it is, there are three directory trees you need to worry about:

  1. webapp
  2. webapp/WEB-INF
  3. the rest of your file system
To download a file from within the webapp, you can use plain old <A HREF> or <IMG SRC>.

To download a file from anywhere else -- including the webapp/WEB-INF under WEB-INF -- you need to call a servlet that opens the file and spits out the contents as described above.

Note that the user your servlet engine is running as must have permission to access that file, or you will get a server error.

See also



Is this item helpful?  yes  no     Previous votes   Yes: 1  No: 0



Comments and alternative answers

Comment on this FAQ entry

Amit Ghaste (ghaste@usa.net) writes: Hi, I have to...
Alex Chaffee PREMIUM, Feb 18, 2000  [replies:3]
Amit Ghaste (ghaste@usa.net) writes: Hi, I have to download files from the server to the user, I have code which works just fine in Netscape, but the same is not working in IE. here is the code sample. for a pdf file _________________________
response.setContentType ("application/pdf");
response.setHeader ("Content-Disposition", "attachment; filename=\"syntax.pdf\"");
ServletOutputStream op = response.getOutputStream ();
while ((in != null) && ((length = in.read(buf)) != -1)) 
{
  // the data has already been read into buf
  System.out.println("Bytes read in: " +        Integer.toString(length));
  op.write(buf,0,length);
}
_________________________
I dont want to give direct links to the files itself, if it is the only option left.

Is this item helpful?  yes  no     Previous votes   Yes: 1  No: 0



Reply to this answer/comment  Help  
Re: Amit Ghaste (ghaste@usa.net) writes: Hi, I have to...
Bill Chatfield, Jun 14, 2001
I'm using IE5.0 and jswdk-1.0.1. I have to spell "attachment" as "attachement" to get the PDF to load in the browser instead of downloading. If I spell it as "attachment" it always gives me a download dialog box.

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re: Amit Ghaste (ghaste@usa.net) writes: Hi, I have to...
Brien Hodges, Jul 12, 2001
I am using:
<%@ page contentType="application/download" %>

SO that the page will always be saved to the users harddrive. But I have a problem. When I have a link to my download page the first browser window pops up and says "Run from location.." or "Save file as...".

But if I say Save it the name displayed is some random characters with a .JSP extension. If I save "Run from current location" it then has another save box pop up where I can then save the file and the correct filename is displayed.

Has anyone seen this before and does anyone have a suggestion as to how to fix it?

Thanks,
Brien

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  

Re: Amit Ghaste (ghaste@usa.net) writes: Hi, I have to...
ali javed, Aug 13, 2001
Hello, I used the source code you have used but it is not working. The problem is that one file gets downloaded but on the same page when I cilck some other link, it displays error "getOutputStream() has already been called for this response until I refresh that page. It is an illegalstateException." Please, solve my problem. THANX ali javed

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Solution 2 works great for binary files under netscape,...
Matthew Conway, Mar 15, 2000  [replies:1]
Solution 2 works great for binary files under netscape, and under IE 5 it also downloads the file correctly. Unfortunately IE ends up thinking it still is waiting on something, so the hourglass never goes away, and the globe keeps on spinning. Is there any way to prevent this from happening?

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re: Solution 2 works great for binary files under netscape,...
Benjamin Kallauch, Jul 9, 2001
maybe it is a solution to give it an out.close(), but I am really not sure.

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
I was setting the Content-disposition header to be...
Matthew Conway, Mar 16, 2000  [replies:14]
I was setting the Content-disposition header to be "attachment;filename=foo.zip" in order to provide a suitable default filename for the client's Save As dialog. Setting it instead to be just "filename=foo.zip" got rid of my problem with IE waiting forever.

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re: I was setting the Content-disposition header to be...
vinay salehithal, Sep 27, 2001  [replies:9]
Hi, I am downloading a csv file from the server. I am too facing the same propblem of IE waiting for ever after finishing the download. As per your suggestion I tried to set the Content-Disposition header to just "filename=myfilename.csv", but after doing this, when i click on my download link the save as or open popup is not being shown, instead leads to opening of the csv file in the browser itself. Please let me know if u have any ideas on this

Is this item helpful?  yes  no     Previous votes   Yes: 2  No: 0



Reply to this answer/comment  Help  
Re: I was setting the Content-disposition header to be...
aytac sen, Oct 10, 2001  [replies:8]
Hi, I try to download files from the server also, and the solution that suggests setting Content-Disposition header to just "filename=..." causes the problem you mentioned for some other file types also(like .doc, .mp3).

especially when the ContentType is "APPLICATION/OCTET-STREAM"

So how to avoid this and have the popup window still ?? If any solution is reached can you inform please.

Thanks.

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re: Re: I was setting the Content-disposition header to be...
vinay salehithal, Oct 10, 2001  [replies:7]
Hi, In our case, since we were downloading a csv file we have set the content type to 'application/csv'. Apart from this, the problem was occuring with IE browsers and not with Netscape. We were also facing a problem with IE 5.5 in which once a download link was clicked the other links became unoperational. We managed to solve this(rather a workaround) as follows: 1. Detect the browser type. 2. If(IE5.0) { Content-Disposition: attachment; filename=\"myfilename.csv \";" } else { Content-Disposition: anyWord;filename=\"myfilename.csv \";" } I hope this helps. Regards

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re: I was setting the Content-disposition header to be...
aytac sen, Oct 11, 2001  [replies:6]
I want to explain my situation and what I tried till now:

Part p= getTheAppropriatePartSomeHow();

response.setContentType(p.getContentType());
response.setHeader("Content-Disposition", "filename=\"" + p.getFileName() + "\";");

response.setContentLength(p.getSize());


InputStream is = p.getInputStream();
OutputStream oout = response.getOutputStream();
byte[] b = new byte[4 * 1024];
int len = 0;

       while ((len = is.read(b)) != -1) {
             oout.write(b, 0, len);
        }
        is.close();
        out.flush();
        oout.close();


The important point is the line:

response.setHeader("Content-Disposition", "filename=\"" + p.getFileName() + "\";");
Whatever I try I couldn't get a perfect result from this code…
  • If I leave the code as

    response.setHeader("Content-Disposition", "filename=\"" + p.getFileName() + "\";");
    then:
    If the file can be shown in the browser, then it is shown:
    e.g. x.jpg c.bmp a.eml note.txt

    but not worked for a .doc file and a .mp3 file I couldn't understand why???(Content-Type: APPLICATION/OCTET-STREAM).
    One more thing: it did it well for c.bmp, whose content-type was also APPLICATION/OCTET-STREAM

  • If I have the code as
    response.setHeader("Content-Disposition", "attachment; filename=\"" + p.getFileName() + "\";");
    then: <it forces for a download>
    e.g.
    for a x.jpg file
    BR>it opens a "File Download" Dialog Box, with options "Open file" or "Save to disk"

    if you choose: "Save To Disk" option then it shows the "Save As" dialog with the CORRECT filename, and by pressing OK, it saves the file, but HOURGLASS never goes away(The problem defined before in the thread) to prevent this I tried to follow the answers given here (like just giving the filename in the Content-Disposition, result is explained above.)
    but if you choose: "Open File From Current Location" then it does nothing, and just the HOURGLASS never goes away


  • If I have the code as

    response.setHeader("Content-Disposition", "attachment; filename=\"" + p.getFileName() + "\";");

    NOTE: The difference is that "Content- Disposition" is written WITH A SPACE in between and not like " Content-Disposition", I saw that in

    http://www.jguru.com/faq/view.jsp?EID=252010
    Re: In my servlet I am trying to let the user download… (By seema bhatnagar)

    Then: If the file can be shown in the browser, then it is shown:
    e.g. x.jpg c.bmp a.eml note.txt

    but for c.bmp, whose content-type was also APPLICATION/OCTET-STREAM, and for some other files, it opens a "File Download" Dialog Box, with options "Open file" or "Save to disk"

    if you choose: in both "Save To Disk" and "Open File" options it SHOWS THE FILENAME IN A FALSE way… (Showing the .jsp file's name to be saved) and saves in this format…

    So the only problem with the last case is that IT CAN`T get the correct filenames to where to save the parts.



    ***So since you're reading this sentence, then you probably read all the cases that I tried to explain… If you have any suggestions about how to solve the problems for any case, please share with me, thanks***


Is this item helpful?  yes  no     Previous votes   Yes: 1  No: 0



Reply to this answer/comment  Help  
Re: Re: I was setting the Content-disposition header to be...
vinay salehithal, Oct 11, 2001  [replies:1]
Hi, Do you want all those files to be seen in yr browser or to be saved with Download popup? Also which browser/version are you working with? Looking at yr last case have you tried this: response.setHeader("Content-[space]Disposition", "anyword; filename=\"" + p.getFileName() + "\";");

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re: Re: Re: I was setting the Content-disposition header to be...
aytac sen, Oct 11, 2001
Both can be acceptable. If it CAN show the content in the browser then it is ok... (But download Popup will be better for my case)

In brief;

  • download popup for all types of files is better for me
  • in case that it is easier to construct the other way(I mean -files seen in the browser and download when needed- behaviour like "inline"), then it is acceptable also...

    navigator.appVersion returns 4.0 (compatible; MSIE 5.0; Windows NT; DigExt)

    and yes I tried the case you suggested, it doesn't work at all... It always opens a download popup, asking whether to "Save" or "Open the document" , and in each case: It responds with the .jsp file's name, so it tries to open/save the content as like a text file...
Thanks for any suggestions.. I`m sure that solving that problem will form a useful documentation for that kind of "Downloading File From Server" issue.

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re: Re: I was setting the Content-disposition header to be...
Jonathan Downey PREMIUM, Oct 19, 2001  [replies:3]
Hi,
I had the same problem. Basically we wanted to always trigger the Download from an InputStream with the correct filename being displayed. This code works perfectly with IE 5.5 and Netscape

protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
    String fileToFind = req.getParameter("file");
    
    if(fileToFind == null)      return;
    
    File fname = new File(fileToFind);
    System.out.println("Save As: "+fname.getName() );
    if(!fname.exists())    			return;
    
    FileInputStream istr = null;
    OutputStream ostr = null;
    resp.setContentType("application/binary");
    resp.setHeader("Content-Disposition", "attachment; filename=\"" + fname.getName() + "\";");
    try {  
      istr = new FileInputStream(fname);
      ostr = resp.getOutputStream();
      int curByte=-1;
      
 			while( (curByte=istr.read()) !=-1)
				ostr.write(curByte);
      
      ostr.flush();
    } catch(Exception ex){
      ex.printStackTrace(System.out);
    } finally{
      try {
      	if(istr!=null)  istr.close();
      	if(ostr!=null)  ostr.close();
      } catch(Exception ex){
      	System.out.println("Major Error Releasing Streams: "+ex.toString());
      }
    }  
    try {
    	resp.flushBuffer();
    } catch(Exception ex){
    	System.out.println("Error flushing the Response: "+ex.toString());
  	}
  }

This code uses a FileInputStream. But it's easy to adapt to any stream really. I just used a FileInputStream for demonstration purposes. The actual servlet will be getting the InputStream from an FTP class. Anyone know any problems with this code?

Jonathan

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  

Re: Re: Re: I was setting the Content-disposition header to be...
Jonathan Downey PREMIUM, Oct 19, 2001  [replies:1]
Ooops, the
try {
  resp.flushBuffer();
} catch(Exception ex){
  System.out.println("Error flushing the Response: "+ex.toString());
}

bit should be left out, it keeps throwing a
Error flushing the Response: java.io.IOException: Response has been close
error.

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re: Re: Re: Re: I was setting the Content-disposition header to be...
aytac sen, Oct 19, 2001

the logic behind the code is right.. the problem is with IE, and with the way they handle the

response.setHeader("Content-Disposition", "attachment;filename=\"" + fname + "\";");


so i can't find a solution to "hourglass staying busy"

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re[3]: I was setting the Content-disposition header to be...
Vipul Khalasi, Oct 25, 2007
Dear your code is not working on Moziila browser when i try to download zip file it's working fine on IE. Give me solution as soon as possible.

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re: I was setting the Content-disposition header to be...
shree m, Jan 9, 2002  [replies:3]
Hi all!
I can download csv data to open in excel properly. I'm using only IE 5.0 and above and jrun3.1 server. I'm posting the data (generated on the client side) as follows:
<html>
<body>
<FORM name="csv_form" action="http://localhost:8000/csvpingserver/mycsvfile.csv"
method= "post">
       <INPUT type= "hidden" value='a 70k chars looooong string'
       name= "csv_data">
       <INPUT id=btn_Download type=submit value=Download>
</form>
</body>
</html>

Servlet is as follows:
    public void service(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException
{
// Set Content Type
res.setContentType("application/ms-excel");
// Init Locals
String method = req.getMethod();
OutputStream os = res.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF8");
PrintWriter out = new PrintWriter(osw);
// Validate Method
if(method.compareToIgnoreCase("POST") != 0)
{
out.println("Error:");
out.close();
return;
}
try {
// Get CSV Data
String strCsvData = req.getParameter("csv_data");
// Return CSV Data
if(strCsvData != null) {
char [] chCsvData = strCsvData.toCharArray();
res.setHeader("Content-Disposition", "attachment;filename=test.csv");
res.setIntHeader("Content-length", chCsvData.length);
out.write(chCsvData);
out.flush();

}
else
out.println("Error: No CSV Data found!");
out.close();
}
catch (Exception e)
{
System.err.println("Caught Exception: " + e.getMessage());
out.println("Error: Invalid Data sent to Servlet!");
out.close();
}
finally {
if(out != null) out.close();
if(osw != null) osw.close();
}
}

The above code shows the open/save dialog TWICE (!?) before 'opening' it in excel. This does not happen if I save it on the disk. I tried different combinations of setContentType(), Content-Disposition, content-length, flush so-on without success. What should be the combination so that a user can view it in excel (not in the browser)?

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re[2]: I was setting the Content-disposition header to be...
Nagaraja Settra, Nov 15, 2004  [replies:1]
Do this in your code to fix the issue of open/save dialog showing TWICE,
res.setContentType("application/download");
res.setHeader("Content-Disposition", "filename=\"locationOutput.csv\"");
Notice the following things here,
1. Content type is set to application/download
2. There is no attachment in the Content-Disposition header.

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re[3]: I was setting the Content-disposition header to be...
Umesh Singh, Jan 8, 2007
Hi, I have got stuck to same situation... when I try to download file in .csv format just after uploading some new data into a pre-exixting file for confirmation to update the amendment done in preexisting file to the database...clicking "Download" button,it gets opened in the browser itself...and also do not display the file download(open/save/cancel) window...it directly opens it in IE... I want it to prompt for open/save/cancel... then on selecting "open",shud open it in seperate excel sheet not in IE...The code follows:
resp.setContentType("application/csv");
		resp.addHeader("Content-Disposition", "filename=Confirm.csv;");
		PrintWriter out = resp.getWriter();
		BufferedWriter wr = new BufferedWriter(out);
		
		//Create confirmation report formatter and pass in validated vehicles
		ConfirmationReportFormatter crf = new ConfirmationReportFormatter();
		
		String report = crf.generateReport(uploadData);
		
		wr.write(report);
		wr.flush();

Please do help me in this regard...

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
« previous beginning next »


Ask A Question



 
Related Links

JSP FAQ

JSP Forum

Sun's JSP home page

SUN's JSP-Interest mailing archive

IBM's "Introduction to JSP" online course

JSP Insider

JavaScript FAQ

JavaScript Forum

Netscape JavaScript Reference

Focus on JavaScript

Servlets FAQ

Servlets Forum

Servlet-related resource list from Purple Technology

jGuru JSP FAQ

Sun Servlet Home Page

java.isavvix.com

Wish List
Features
About jGuru
Contact Us

 



The Network for Technology Professionals

Search:

About Internet.com

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | E-mail Offers