前言
上一篇介绍了文件上传,传送门:Java实现文件上传功能,这次简单介绍一下文件下载功能
实现思路
文件下载简单来说就是在读取文件的基础上多了一层与HTTP的通信,因此流程的改变如下:
原:与计算机文件系统交互
现:与HTTP通信交互→与计算机文件系统交互
实现代码
重点会写在注释中,下面直接贴代码
1、业务层 (省略类的代码,此处只有方法)
public void downloadLogFile(HttpServletRequest request, HttpServletResponse response) {
try {
//从网站上下载文件时,需要知道下载的是哪一个文件,因此需要获取文件名称(包括后缀)
String logNameReq = request.getParameter("logName");
//关键点,需要获取的文件所在文件系统的目录,定位准确才可以顺利下载文件
String filePath = "D:\\" + logNameReq;
File file = new File(filePath);
//创建一个输入流,将读取到的文件保存到输入流
InputStream fis = new BufferedInputStream(new FileInputStream(filePath));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 重要,设置response的Header
response.setHeader("Content-Disposition", "attachment;filename=" + new String(logNameReq.getBytes()));
response.setHeader("Content-Length", "" + file.length());
//octet-stream是二进制流传输,当不知文件类型时都可以用此属性
response.setContentType("application/octet-stream");
//跨域请求,*代表允许全部类型
response.setHeader("Access-Control-Allow-Origin", "*");
//允许请求方式
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
//用来指定本次预检请求的有效期,单位为秒,在此期间不用发出另一条预检请求
response.setHeader("Access-Control-Max-Age", "3600");
//请求包含的字段内容,如有多个可用哪个逗号分隔如下
response.setHeader("Access-Control-Allow-Headers", "content-type,x-requested-with,Authorization, x-ui-request,lang");
//访问控制允许凭据,true为允许
response.setHeader("Access-Control-Allow-Credentials", "true");
//创建一个输出流,用于输出文件
OutputStream oStream = new BufferedOutputStream(response.getOutputStream());
//写入输出文件
oStream .write(buffer);
oStream .flush();
oStream .close();
System.out.println("下载日志文件" + logNameReq +"成功");
} catch (Exception e) {
System.out.println("下载日志文件出错,错误原因:" + e);
}
}
2、控制层 (省略类的代码,此处只有方法)
//此处一定要使用Get请求,因为Get与Post对于文件下载这一功能的前后端实现都不一样
@GetMapping("/downloadlog")
public void downloadLog(HttpServletRequest request, HttpServletResponse response) {
service.downloadLogFile(request, response);
}
注意事项
前端调用文件下载接口时,不要用封装好的Get请求直接访问,因为文件下载与普通的get请求有稍许差别,使用window.location访问即可