JavaWeb笔记-22-文件下载

版权声明:转载请联系作者本人!!! https://blog.csdn.net/qq_41307491/article/details/81749885

1、文件下载


下载:向客户端响应字节数据。(原来响应的是html的字符数据)

做法:把一个文件变成字节数组,使用response.getOutputStream();来响应给浏览器

要求:两个头、一个流
    Content-Type头:传递给客户端的MIME类型
        使用 this.ServletContext.getMimeType("文件路径名")方法,得到MIME类型! 传参为文件路径名

    Content-Disposition头:设置是否弹出下载框。 
        默认值为inline,表示在浏览器窗口打开
        设置值为:attachment;filename=xxx;  表示弹出现在框
            filename=后面跟随的是显示在下载框中的文件名称!

    流:要下载的文件数据
        new一个输入流即可

下载步骤:
    1)得到两个头
        Content-Type头:
                使用 this.ServletContext.getMimeType("文件路径名")方法,得到MIME类型! 传参为文件路径名
        Content-Disposition头 (设置为弹窗下载,弹窗中显示处理过编码的名称) 
                String contentDisposition = "attachment;filename="+framname;
    2)得到数据流
        FileInputStream input = new FileInputStream(filename); 

    3)将两个头设置给响应
        response.setHeader("Content-Type", contentType);
        response.setHeader("Content-Disposition", contentDisposition);

    4)将流绑定客户端地址(流往到客户端)
        ServletOutputStream output = response.getOutputStream();

    5)把输入流中的数据写入到输出流中
        IOUtils.copy(input, output);

下载细节
    乱码问题:当下载框显示中文名称时,会出现乱码
        FireFox:Base64编码
        其他浏览器:URL编码。

通用解决方案:
filename = new String("需要处理的文件名".getBytes("GBK"),"IOS-8859-1");

上述方案存在个别特殊字符不能正确显示
解决:使用方法filenameEncoding   

2、代码演示:


public class Download1Servlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /*
         * 下载歌曲:    
         * 两个头、一个流
         * 1.Content-Type
         * 2.Content-Disposition
         * 3.流:文件数据流
         */

        //得到Content-Type头
        //得到文件路径名
        String filename = "C:/Users/11316/Music/思疆调.mp3";

        //处理文件名乱码问题
//      String newfilename = new String("思疆调.mp3".getBytes("GBK"),"ISO-8859-1");
        String framname = filenameEncoding("思疆调.mp3",request);

        //通过文件路径名称获取MIME类型
        String contentType = this.getServletContext().getMimeType(filename);

        //得到 Content-Disposition头 (设置为弹窗下载,弹窗中显示处理过编码的名称) 
        String contentDisposition = "attachment;filename="+framname;

        //流   通过文件路径名的得到数据流
        FileInputStream input = new FileInputStream(filename); 

        //为响应设置两个头: Content-Type、Content-Disposition
        response.setHeader("Content-Type", contentType);
        response.setHeader("Content-Disposition", contentDisposition);

        //获取绑定了客户端的流(流往到客户端)
        ServletOutputStream output = response.getOutputStream();

        //把输入流中的数据写入到输出流中
        IOUtils.copy(input, output);

        //关闭流
        input.close();
    }

    // 用来对下载的文件名称进行编码的! 根据不同浏览器不同编码处理
    public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException {
        String agent = request.getHeader("User-Agent"); //获取浏览器
        if (agent.contains("Firefox")) {
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filename = "=?utf-8?B?"
                    + base64Encoder.encode(filename.getBytes("utf-8"))
                    + "?=";
        } else if(agent.contains("MSIE")) {
            filename = URLEncoder.encode(filename, "utf-8");
        } else {
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }
}

知识点: enctype属性
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_41307491/article/details/81749885