服务器向客户端浏览器发送文件时,如果是浏览器支持的文件类型(如.txt.pdf.sql.jpg.git.html等),一般会默认使用浏览器打开,直接在浏览器中显示。

要对服务器发送文件进行下载,需要进行相关下载设置:

  • 如果是chrome浏览器,设置 response.setContentType("application/x-msdownload");
                 或者 response.setContentType("application/octet-stream");
                 或者 response.setHeader("Content-Disposition", "attachment");
      即可对服务器向客户端浏览器发送的文件进行下载

  • 如果是IE浏览器,设置 response.setHeader("Content-Disposition", "attachment");可以实现对服务器向客户端浏览器发送的文件进行下载。
      但仅设置 response.setContentType("application/x-msdownload");
         或者 response.setContentType("application/octet-stream"); 不会对服务器发送文件进行下载。



Content-Disposition是MIME协议的扩展,Content-Disposition可以控制用户请求所得内容存为一个文件时提供一个默认的文件名,文件是直接在浏览器上显示或弹出文件下载对话框下载。


格式说明:

content-disposition = “Content-Disposition” “:” disposition-type *( “;” disposition-parm )


字段说明:

  • Content-Disposition为属性名

  • disposition-type是文件处理方式,如(attachment为以附件方式下载;inline为在浏览器页面中打开显示)

  • disposition-param为默认保存时的文件名

在这里插入图片描述

服务端代码:

response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));

或

response.setHeader("Content-Disposition", "inline");

具体实例:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/**
 * @Author: 落叶无痕
 * @Date: 2020/6/3 16:32
 */
@Controller
public class UploadController {

    @GetMapping("/download/{filename}")
    public void downloadFile(@PathVariable("filename") String filename, HttpServletResponse response) throws UnsupportedEncodingException {

        if(filename != null){
            //获取要下载的文件对象
            File file = new File("D:/jianli/", filename);
            if(file.exists()){
//                response.setContentType("application/x-msdownload");
//                response.setContentType("application/octet-stream");
//                response.setHeader("Content-Disposition", "inline");
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));

                InputStream input = null;
                OutputStream output = null;
                try{
                    input = new FileInputStream(file); //创建文件输入流对象
                    output = response.getOutputStream(); //创建文件输出流对象
                    byte[] buf = new byte[1024]; //定义一个字节数组作为缓冲区,并指定一次读取1024个字节
                    int len; //记住读入缓冲区的字节长度
                    while ((len = input.read(buf)) != -1){ //判断文件是否读完(读完后会返回-1)
                        //注意不要用output.write(buf); 否则可能导致最终写入的文件比原文件大,如果文件是图片的话,那么就会失真
                        output.write(buf, 0, len); //从buf缓冲区中读取数据,从第一个字节开始读,一次读取len,并将读取出来的数据写入文件输出流对象中
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    //最后记得关闭IO流
                    try {
                        input.close();
                        output.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

}

备注:

  • IE浏览器下载文件时,会弹出文件下载提示框提示你打开、保存或取消。即使选择打开,也会使用相关联的程序比如记事本打开,而不是IE直接打开了。
    -

  • Chorme浏览器不会提示你是打开还是保存,而是直接进行下载
    在这里插入图片描述


https://www.cnblogs.com/SkyGood/p/3959118.html

https://www.jb51.net/article/30565.htm

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐