Cannot download a file using HttpServletResponse

14,069

Solution 1

As you mentioned MyHttpServletResponse is a class that eclipse has produced by default when I quick fix the error generated, that seems to be the problem.

Your code should be inside some servlet/JSP and the HttpServletResponse object should be taken from the container (which is passed to service/doGet/doPost methods).

What you are using is a default/dummy implementation of HttpServletResponse which gives response.getOutputStream(); as null. If you use the container provided objects, your problem will be solved.

Solution 2

If you are using a Java EE platform to perform the download operation to occur then the safest way is to do it through a servlet. A Sample Download servlet should Look like below,

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.*; 
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class DownloadFile extends HttpServlet{
    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();

        // Prepare the File Read.
        String fileName = request.getParameter("fileName");
        fileName = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
        String extension = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
        String filePath = "C:/temp/" + fileName;
        FileInputStream fileToDownload = new FileInputStream(filePath);

        // Prepare the Headers.
        if (extension.equalsIgnoreCase("txt")) {
            response.setContentType("text/html");
        } else if (extension.equalsIgnoreCase("doc")) {
            response.setContentType("application/msword");
        } else if (extension.equalsIgnoreCase("pdf")) {
            response.setContentType("application/pdf");
        } else if (extension.equalsIgnoreCase("jpg")) {
            response.setContentType("image/jpeg");
        } else if (extension.equalsIgnoreCase("jpeg")) {
            response.setContentType("image/jpeg");
        }
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        response.setContentLength(fileToDownload.available());

        // Download the file.
        int c;
        while ((c = fileToDownload.read()) != -1) {
            out.write(c);
        }
        out.flush();
        out.close();
        fileToDownload.close();
    }
}
Share:
14,069
Sunmit Girme
Author by

Sunmit Girme

A coding enthusiast. A newbie. Interested in Java. Now looking forward learning JSP, Servlets, Java Script and jQuery. Love to work on databases!

Updated on June 04, 2022

Comments

  • Sunmit Girme
    Sunmit Girme almost 2 years

    I want to download a MS Word 2003 document that I am creating with the content myString in it. I have used the following code:

    BufferedReader reader = new BufferedReader(new FileReader(templatePathFilename));
    HttpServletResponse response = new MyHttpServletResponse();
    response.setContentType ("application/msword"); 
    response.setHeader ("Content-Disposition", "attachment; filename=\""+outgoingFileName); 
    ServletOutputStream myOut = response.getOutputStream();
    myOut.write(myString.getBytes());
    myOut.flush();
    myOut.close();
    

    But the line myOut.write(myString.getBytes()) gives a NullPointerException. MyHttpServletResponse is a class that eclipse has produced by default when I quick fix the error generated. Do I need to modify that class? Can anyone please help!

    EDIT: The actual code i am working on is as below:

    BufferedReader reader = new BufferedReader(new FileReader(templatePathFilename));
    String outgoingFileName = outputPathFilename;
    response.setContentType("application/msword"); 
    response.setHeader("Content-Disposition", "attachment; filename="+outgoingFileName);
    OutputStream myOut = response.getOutputStream();
    try {
    String thisLine;
    while ((thisLine = reader.readLine()) != null) {
        if(thisLine.contains("##"))
        {
        for (java.util.Enumeration e = FrontSheetMap.keys(); e.hasMoreElements();{
         String name = (String) e.nextElement();
         String value = FrontSheetMap.get(name).toString();
         thisLine= thisLine.replaceAll("##" + name.toUpperCase() + "##", value);
        }
       }
       myOut.write(thisLine);
       myOut.write("\n");
      }
      myOut.flush();
    }catch(Exception e){}
    

    The while loop replaces the placeholders in the input file with required values and the new content in thisLine is to be written on the output file. I need a download option which pops up on clicking the link which executes this code.

  • Sunmit Girme
    Sunmit Girme about 12 years
    Thanks, the NullPointerException does not occuranymore. But the function still does not pop-up a decision box to download the word document. How can I achieve that?
  • Sunmit Girme
    Sunmit Girme about 12 years
    It does not download. The code executes, but it is supposed to give a pop-up to save the file, but it doesn't.
  • Sourav Bairagi
    Sourav Bairagi about 12 years
    In the above code u can see i am reading the file from the server location on "C:\Temp" ok so u have to change the " filePath " as per your requirement, any yes this servlet will generate a save dialog box to save the file in your desired location.
  • Half Blood Prince
    Half Blood Prince over 7 years
    @SunmitGirme Same problem. Any solution?