通过搜索整理,自行简化后,普遍采用以下两种实现方式:
1.使用HttpServletResponse实现:
@RequestMapping("/downloadTraditional")
public void download1(HttpServletResponse response) throws IOException{
/*
* Files和Paths类是jdk1.7版本后提供的
* */
//1.文件路径
String basePath="G:\\upload\\";
String fileName="03994809-4e3b-44dd-a4fb-58412beba563.txt";
//2.获取path对象
Path path=Paths.get(basePath+fileName);
//文件类型(二进制)[可选]
//response.setContentType( "application/octet-stream");
//显示文件大小[可选]
//response.setHeader("Content-Length",""+Files.size(path));
//3.Content-Disposition常用取值有:attachment和inline,
//attachment:打开下载框
//inline:将文件直接显示在页面
response.setHeader("Content-Disposition","attachment;filename="+fileName+"");
//4.向客户端写数据
response.getOutputStream().write(Files.readAllBytes(path));
}
2.使用ResponseEntity实现(较为复杂):
@RequestMapping("/download")
public ResponseEntity<byte[]> download() throws IOException{
//1.文件路径
String basePath="G:\\upload\\";
String fileName="543257dd33c549878bcc29369711fe9d.jpg";
//2.创建path对象(Files和Paths是java1.7新增的类)
Path path=Paths.get(basePath+fileName);
//3.创建请求头对象
HttpHeaders headers=new HttpHeaders();
//4.设置返回类型为二进制流
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//5.设置文件名,其中attachment代表以下载方式打开,若替换为inline,则会直接显示文件内容在网页上
headers.setContentDispositionFormData("attachment", fileName);
//6.设置页面显示文件大小,若无要求可以不设置
headers.setContentLength(Files.size(path));
//7.返回值(下载文件对应的字节数组,头部对象,状态码),状态码OK对应200,其他常见的例如404 和 500
return new ResponseEntity<byte[]>(Files.readAllBytes(path), headers, HttpStatus.OK);
}
总结:
1.经过自己简化后的方法,因为采取一次性将文件读入内存,所以在对大文件应用的时候不是很友好,有两个弊端:
1.1 无法支持断点续传;
1.2 下载文件过大会造成内存溢出。
2.可以对传统的方法进一步简化如下,仅需要两行代码即可实现文件下载,对于小文件来说十分方便:
@RequestMapping("/downloadTraditional")
public void download1(HttpServletResponse response) throws IOException{
response.setHeader("Content-Disposition","attachment;filename=test.txt");
response.getOutputStream().write(Files.readAllBytes(Paths.get("G:\\upload\\test.txt")));
}