服务器向客户端浏览器发送文件时,如果是浏览器支持的文件类型(如.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浏览器不会提示你是打开还是保存,而是直接进行下载