若依文件下载
·
前端请求
function downloadFile(value){
window.location.href = ctx + "common/download/resource?resource=" + value;
}
- 函数名: downloadFile - 文件下载功能
- 参数: value - 要下载文件的标识(通常是文件路径或文件名)
- ctx: 项目上下文路径(如:http://localhost:8080/项目名/)
- “common/download/resource”: 通用下载接口路径
- ?resource= + value: 传递文件资源参数
- window.location.href: 改变浏览器地址,发起GET请求浏览器接收到文件流响应后自动触发下载
http://localhost:8080/项目名/common/download/resource?resource=/uploads/2023/document.pdf
后端响应
/**
* 本地资源通用下载
*/
@GetMapping("/common/download/resource")
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
throws Exception
{
// 本地资源路径
//作用: 获取配置文件中的文件上传存储路径
String localPath = Global.getProfile();
// 数据库资源地址
//Constants.RESOURCE_PREFIX: 资源前缀常量(如:/profile 或 /upload)
//StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX):
//从完整资源路径中截取前缀之后的部分
//resource = "/profile/images/photo.jpg" → 截取后得到 "/images/photo.jpg"
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
// 下载名称
//作用: 从完整路径中提取纯文件名示例: "D:/upload/images/photo.jpg" → "photo.jpg"
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
//设置字符编码,确保中文正确处理
response.setCharacterEncoding("utf-8");
//设置内容类型为文件下载
response.setContentType("multipart/form-data");
//关键头,告诉浏览器以下载方式处理
response.setHeader("Content-Disposition",
"attachment;fileName=" + FileUtils.setFileDownloadHeader(request, downloadName));
//处理文件名编码,解决浏览器兼容性问题
FileUtils.writeBytes(downloadPath, response.getOutputStream());
}
}
String localPath = Global.getProfile();
//作用: 从系统全局配置中获取文件存储的根目录路径
//返回值: 文件上传和下载的基础目录
在 application.yml 或相关配置文件中:
# 文件上传配置
file:
upload:
path: D:/uploadFiles
# 或者
ruoyi:
profile: /home/app/uploads
返回值
// 可能的返回值示例:
Windows: "D:/uploadFiles/"
Linux: "/home/app/uploads/"
相对路径: "./uploads/"
writeBytes执行过程
// FileUtils.writeBytes 的简化实现
public static void writeBytes(String filePath, OutputStream os) throws IOException {
//作用: 根据文件路径创建File对象,功能: 封装文件路径,提供文件操作的基本方法
File file = new File(filePath);
if (file.exists()) {
//建立从文件到程序的字节输入通道。作用: 允许程序读取文件的原始字节数据
//创建文件输入流 (FileInputStream fis) - 建立从文件到程序的读取通道
FileInputStream fis = new FileInputStream(file);
//缓冲区大小: 1024字节(1KB)
//避免一次性读取大文件导致内存溢出
//提高I/O效率,减少磁盘访问次数
//平衡内存使用和读取性能
//创建字节数组缓冲区 (byte[] buffer) - 作为临时的数据中转站
byte[] buffer = new byte[1024];
int length;
//从文件读取数据到缓冲区,从fis读取数据到buffer (fis.read(buffer))
while ((length = fis.read(buffer)) != -1) {
//将缓冲区中的数据写入输出流,只写入实际读取的字节数(0到length-1),避免写入无效数据
//将buffer中的数据写入HTTP输出流 (os.write(buffer, 0, length))
os.write(buffer, 0, length);
}
fis.close();
} else {
throw new FileNotFoundException("文件不存在: " + filePath);
}
}
流程
从web端发起下载请求,后端先获取下载的基准路径,之后获取相对路径,最后获得完整路径,最后进行响应。响应时,先根据该路径创建File对象验证文件存在性。确认文件存在后,创建文件输入流(fis)连接到该文件,同时准备字节数组作为缓冲区。通过循环读取:从文件输入流读取数据到缓冲区,再将缓冲区的数据写入HTTP响应输出流,直到文件内容全部传输完毕。
更多推荐


所有评论(0)