JAVA文件下载功能问题解决日志

  今天给报告系统做了个下载功能,遇到了挺多问题,通过查资料一一解决了。

1、首先遇到的问题是:java后台的输出流输出之后,没有任何报错,浏览器端不弹出保存文件的对话框,原本是ajax请求到后台的controller方法中添加了下载的方法,type和async两个参数的四种组合都不行,弃用ajax,用window.location.href='file/download?path='+file;重新发一个新的下载请求之后,保存对话框终于弹出。

2、弹出之后,发现文件名乱码,后台的解决方案代码如下:

      private static final String CHARSET = "utf-8";
String agent = request.getHeader("User-Agent").toLowerCase(); if (agent != null && (agent.indexOf("msie") != -1 || (agent.indexOf("rv") != -1 && agent.indexOf("firefox") == -1))) { fileName = URLEncoder.encode(file.getName(), "UTF-8"); } else { fileName = new String(file.getName().getBytes(CHARSET), "ISO8859-1"); }

3、后台一直在报错getWriter() has already been called for this response,通过报错内容大概可以看出ServletOutputStream out = response.getOutputStream();这个应该是个单例的,但是又没有发现别的地方在调用这个方法获取输出流,仔细测试发现,每次把所有的请求全部关闭之后,第一次不会出问题,之后再请求就会报错,把后面的out.close();注释掉,报错就解决了。

4、前台拼文件路径的方法

                var file;
                var path = $("#lujing").val();
                if(path.lastIndexOf('\\')!=path.length-1){
                    //console.info("不以斜杠结尾");
                    file = $("#lujing").val() + "\\" + $("#city").val() + "市" + $("#year1").val()
                    + $("#month1").val() + "电商数据分析报告.doc";
                } else {
                    //console.info("以斜杠结尾");
                    file = $("#lujing").val() + $("#city").val() + "市" + $("#year1").val()
                    + $("#month1").val() + "电商数据分析报告.doc";
                }
                
                window.location.href='file/download?path='+file;

5、导出controller

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
 * @author 作者 Jeffy
 * @version 
 * 
 */
@Controller  
public class FileController{
    //Spring这里是通过实现ServletContextAware接口来注入ServletContext对象  

    private static final String CHARSET = "utf-8";
    @RequestMapping("/exportreport/file/download")  
    public static void fileDownload(HttpServletResponse response, HttpServletRequest request,
            String path) throws UnsupportedEncodingException{

        File file = new File(path);
        String fileName;
        String agent = request.getHeader("User-Agent").toLowerCase();
        if (agent != null && (agent.indexOf("msie") != -1 ||   
                (agent.indexOf("rv") != -1 && agent.indexOf("firefox") == -1))) {
            fileName = URLEncoder.encode(file.getName(), "UTF-8"); 
        } else {  
            fileName = new String(file.getName().getBytes(CHARSET), "ISO8859-1");
        }

//        response.reset(); //非常重要
        //1.设置文件ContentType类型,这样设置,会自动判断下载文件类型
        response.setContentType("multipart/form-data");
        response.setContentType("application/OCTET-STREAM;charset=UTF-8");
        //2.设置文件头:最后一个参数是设置下载文件名(假如我们叫a.pdf)
        response.setHeader("Content-Disposition", "attachment;fileName="+fileName);
        ServletOutputStream out;

        try {  
            FileInputStream inputStream = new FileInputStream(file);
  
            //3.通过response获取ServletOutputStream对象(out)  
            out = response.getOutputStream();  
  
            int b = 0;  
            byte[] buffer = new byte[512];  
            while ((b = inputStream.read(buffer)) != -1){  
                //4.写到输出流(out)中  
                out.write(buffer,0,b);  
            }  
            inputStream.close();  
//            out.close();  
//            out.flush();  

        } catch (IOException e) {
            e.printStackTrace();  
        }  
    }  

}

以上便是遇到的java文件下载功能全部问题,可能还有暂时没有测试出的问题,后续发现问题及时更新,也请大家多多批评指正。