SpringBoot中實現多文件打包下載的兩種方案
在Spring Boot中實現多文件打包下載,主要通過將多個文件壓縮為ZIP格式并返回給客戶端。以下是兩種典型實現方案:
??一、本地文件打包下載??
??核心步驟??
- ??接收文件列表參數??
通過@RequestParam List<String> filenames接收前端傳遞的文件名列表。 - ??動態(tài)生成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
??動態(tài)壓縮云存儲文件??
從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);
}
}
??優(yōu)化點??:
- 直接流式傳輸,避免內存溢出。
- 支持斷點續(xù)傳(需結合HTTP Range請求)。
??三、注意事項??
- ??內存管理??
大文件建議使用流式壓縮(如ZipOutputStream),避免OutOfMemoryError。 - ??路徑安全??
使用normalize()過濾非法路徑,防止路徑遍歷攻擊。 - ??異常處理??
捕獲IOException并返回明確錯誤狀態(tài)碼(如404文件不存在)。 - ??擴展性??
可結合分片下載(Range請求)支持大文件斷點續(xù)傳。
??四、前端調用示例??
// 使用Fetch API觸發(fā)下載
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多文件打包下載內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Mybatis Generator最完美配置文件詳解(完整版)
今天小編給大家整理了一篇關于Mybatis Generator最完美配置文件詳解教程,非常不錯具有參考借鑒價值,感興趣的朋友一起學習吧2016-11-11
深入Spring Boot之ClassLoader的繼承關系和影響
這篇文章主要介紹了深入Spring Boot之ClassLoader的繼承關系和影響,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06

