SpringBoot中实现多文件打包下载的两种方案
作者:IT界Tony哥
在Spring Boot中实现多文件打包下载,一般是将多个文件压缩成一个ZIP文件再进行下载,以下是两种典型实现方案以及代码示例,需要的朋友可以参考下
在Spring Boot中实现多文件打包下载,主要通过将多个文件压缩为ZIP格式并返回给客户端。以下是两种典型实现方案:
一、本地文件打包下载
核心步骤
- 接收文件列表参数
通过@RequestParam List<String> filenames接收前端传递的文件名列表。 - 动态生成ZIP文件
使用ZipOutputStream将文件逐个写入内存流,避免生成物理文件。 - 设置响应头
通过Content-Disposition指定文件名,Content-Type设置为application/zip。
代码示例
@GetMapping("/download-multiple")
public ResponseEntity<byte[]> downloadMultipleFiles(@RequestParam List<String> filenames) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos)) {
for (String filename : filenames) {
Path filePath = Paths.get("/path/to/files").resolve(filename).normalize();
if (Files.exists(filePath)) {
ZipEntry zipEntry = new ZipEntry(filename);
zos.putNextEntry(zipEntry);
Files.copy(filePath, zos);
zos.closeEntry();
}
}
zos.finish();
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="files.zip"");
return ResponseEntity.ok().headers(headers).body(baos.toByteArray());
} catch (IOException e) {
return ResponseEntity.internalServerError().build();
}
}
关键点:
- 使用
try-with-resources自动关闭流,避免资源泄漏。 normalize()方法防止路径遍历攻击(如../../)。- 内存中生成ZIP,适合小文件场景。
二、云存储(MinIO)集成方案
若文件存储在云存储(如MinIO),需先获取文件流再压缩:
实现步骤
配置MinIO客户端
添加依赖并配置MinIO连接信息:
minio: url: http://localhost:9000 accessKey: your-key secretKey: your-secret bucketName: your-bucket
动态压缩云存储文件
从MinIO获取文件流,直接写入ZIP输出流:
@Autowired
private MinioClient minioClient;
@GetMapping("/download-zip")
public void downloadZip(@RequestParam List<String> fileNames, HttpServletResponse response) {
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=download.zip");
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
for (String fileName : fileNames) {
try (InputStream inputStream = minioClient.getObject(
GetObjectArgs.builder().bucket(bucketName).object(fileName).build())) {
ZipEntry zipEntry = new ZipEntry(fileName);
zos.putNextEntry(zipEntry);
IOUtils.copy(inputStream, zos);
zos.closeEntry();
}
}
} catch (Exception e) {
throw new RuntimeException("下载失败", e);
}
}
优化点:
- 直接流式传输,避免内存溢出。
- 支持断点续传(需结合HTTP Range请求)。
三、注意事项
- 内存管理
大文件建议使用流式压缩(如ZipOutputStream),避免OutOfMemoryError。 - 路径安全
使用normalize()过滤非法路径,防止路径遍历攻击。 - 异常处理
捕获IOException并返回明确错误状态码(如404文件不存在)。 - 扩展性
可结合分片下载(Range请求)支持大文件断点续传。
四、前端调用示例
// 使用Fetch API触发下载
fetch(`/download-multiple?filenames=file1.txt,file2.jpg`, {
method: 'GET'
}).then(response => {
const blob = new Blob([response.blob()]);
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'files.zip';
link.click();
});
通过上述方案,可灵活实现本地或云存储的多文件打包下载,根据实际需求选择内存或流式处理。
到此这篇关于SpringBoot中实现多文件打包下载的两种方案的文章就介绍到这了,更多相关SpringBoot多文件打包下载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
