无法使用HttpServletResponse下载文件

时间:2012-04-10 05:38:02

标签: java file-io ms-word nullpointerexception

我想下载我正在创建的MS Word 2003文档,其中包含内容myString。 我使用了以下代码:

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();

但是行myOut.write(myString.getBytes())给出了NullPointerException。 MyHttpServletResponse是我快速修复生成的错误时默认生成的类。我需要修改该课程吗? 任何人都可以帮忙!

编辑:我正在处理的实际代码如下:

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){}

while循环使用所需的值替换输入文件中的占位符,并在thisLine中将新内容写入输出文件。我需要一个下载选项,单击执行此代码的链接会弹出。

3 个答案:

答案 0 :(得分:2)

正如你所提到的MyHttpServletResponse 是我快速修复生成的错误时默认生成的一个类,这似乎是个问题。

您的代码应位于某个servlet / JSP 中,HttpServletResponse对象应从容器中获取(传递给service / doGet / doPost方法)。

您正在使用的HttpServletResponse的默认/虚拟实现,它将response.getOutputStream();视为null。如果您使用容器提供的对象,您的问题将得到解决。

答案 1 :(得分:2)

如果您使用Java EE平台执行下载操作,那么最安全的方法是通过servlet执行此操作。示例下载servlet应如下所示,

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();
    }
}

答案 2 :(得分:0)

将文件名添加到标题中,如下所示(文件名应该包含扩展名,如果你有一个名为abc的文件名,文件名应该是abc.doc“即扩展名”),无需检查扩展名然后设置内容类型

httpServletResponse.addHeader(“Content-Disposition”,“attachment; filename =”                       + fileName);

其余代码保持不变并立即尝试,您应该能够看到一个弹出窗口,询问您是否允许打开此word文档。

下面是一个适用于我的代码snipet

        OutputStream outputStream=httpServletResponse.getOutputStream();
        httpServletResponse.addHeader("Content-Disposition", "attachment; filename="
                  + fileName);



        //**Take the data from input stream and write it on outputstream
        try{
            IOUtils.copy(documentumClientSession.getFile(fileName,dbpNum), outputStream);
        }catch(Exception exp){
            exp.printStackTrace();
        }

我正在使用apache commons api,这就是为什么你可以看到org.apache.commons.io.IOUtils正在使用的类,但你可以在代码中用你自己的循环替换它。