要在 Spring Boot 中使用 MinIO 实现多文件打包成一个压缩文件并下载,主要分为以下几个步骤:
如果还没有添加 MinIO 依赖,可以手动下载 MinIO 客户端库,或者直接用 Maven 来管理依赖:
<dependency>
<groupId>io.miniogroupId>
<artifactId>minioartifactId>
<version>8.3.5version>
dependency>
在 application.properties
中添加 MinIO 配置:
minio.url=http://localhost:9000
minio.accessKey=your-access-key
minio.secretKey=your-secret-key
minio.bucketName=your-bucket
然后在 @Configuration
类中配置 MinIO 客户端:
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MinioConfig {
@Value("${minio.url}")
private String url;
@Value("${minio.accessKey}")
private String accessKey;
@Value("${minio.secretKey}")
private String secretKey;
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint(url)
.credentials(accessKey, secretKey)
.build();
}
}
在服务类中添加下载和压缩方法,以下代码会将指定的文件列表压缩成一个 ZIP 并返回给客户端。
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Service
public class MinioService {
@Autowired
private MinioClient minioClient;
@Value("${minio.bucketName}")
private String bucketName;
public void downloadFilesAsZip(List<String> fileNames, HttpServletResponse response) {
try {
// 设置响应头,文件名为 download.zip
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=download.zip");
// 创建 ZIP 输出流
try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
for (String fileName : fileNames) {
// 获取每个文件的输入流
try (InputStream inputStream = minioClient.getObject(
GetObjectArgs.builder().bucket(bucketName).object(fileName).build())) {
// 创建 ZIP 文件条目
zipOut.putNextEntry(new ZipEntry(fileName));
// 将文件数据写入 ZIP
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) >= 0) {
zipOut.write(buffer, 0, length);
}
zipOut.closeEntry(); // 结束该条目的写入
}
}
zipOut.finish(); // 完成 ZIP 文件
}
} catch (Exception e) {
throw new RuntimeException("Error occurred while downloading files as zip", e);
}
}
}
在控制器中定义一个方法,接收前端的请求并调用服务类进行压缩与下载。
@RestController
public class FileDownloadController {
@Autowired
private MinioService minioService;
@GetMapping("/download-zip")
public void downloadZip(@RequestParam List<String> fileNames, HttpServletResponse response) {
minioService.downloadFilesAsZip(fileNames, response);
}
}
现在可以通过 HTTP GET 请求测试该功能:
GET http://localhost:8080/download-zip?fileNames=file1.txt&fileNames=file2.jpg&fileNames=file3.pdf
这个实现将从 MinIO 读取文件流,逐一压缩到 ZIP 中,并通过 HTTP 响应流返回给客户端。
SpringBoot+minio实现多文件下载时在minio指定的桶名下面生产一个文件夹,将需要下载放到这个文件夹中,并把这个文件夹打成一个压缩包后进行下载,下载成功后删除这个文件夹
在使用 Spring Boot 和 MinIO 实现上述功能时,可以按以下步骤操作:
以下是实现的详细步骤和代码。
确保 MinIO 客户端配置正确。使用 application.properties
配置 MinIO 相关信息。
minio.url=http://localhost:9000
minio.accessKey=your-access-key
minio.secretKey=your-secret-key
minio.bucketName=your-bucket
并创建 MinIO 客户端配置类:
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MinioConfig {
@Value("${minio.url}")
private String url;
@Value("${minio.accessKey}")
private String accessKey;
@Value("${minio.secretKey}")
private String secretKey;
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint(url)
.credentials(accessKey, secretKey)
.build();
}
}
在服务类中添加方法来实现各步骤。
import io.minio.CopyObjectArgs;
import io.minio.MinioClient;
import io.minio.RemoveObjectArgs;
import io.minio.GetObjectArgs;
import io.minio.ObjectWriteResponse;
import io.minio.UploadObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Service
public class MinioService {
@Autowired
private MinioClient minioClient;
@Value("${minio.bucketName}")
private String bucketName;
// 将需要下载的文件放入临时文件夹并压缩下载
public void downloadFolderAsZip(List<String> fileNames, HttpServletResponse response) {
String tempFolderName = "temp-folder-" + UUID.randomUUID(); // 随机生成临时文件夹名称
try {
// 上传文件到临时文件夹
for (String fileName : fileNames) {
String objectName = tempFolderName + "/" + fileName;
// 复制原始文件到临时文件夹
minioClient.copyObject(
CopyObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.source(bucketName + "/" + fileName)
.build()
);
}
// 设置响应头
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=download.zip");
// 创建 ZIP 输出流
try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
for (String fileName : fileNames) {
String objectName = tempFolderName + "/" + fileName;
// 获取临时文件夹中的每个文件流
try (InputStream inputStream = minioClient.getObject(
GetObjectArgs.builder().bucket(bucketName).object(objectName).build())) {
// 写入 ZIP 条目
zipOut.putNextEntry(new ZipEntry(fileName));
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) >= 0) {
zipOut.write(buffer, 0, length);
}
zipOut.closeEntry(); // 结束条目写入
}
}
zipOut.finish(); // 完成 ZIP 文件
}
// 下载完成后删除临时文件夹
deleteFolder(tempFolderName);
} catch (Exception e) {
throw new RuntimeException("Error occurred while downloading folder as zip", e);
}
}
// 删除指定文件夹及其内容
private void deleteFolder(String folderName) {
try {
Iterable<Result<Item>> items = minioClient.listObjects(ListObjectsArgs.builder()
.bucket(bucketName)
.prefix(folderName + "/")
.recursive(true)
.build());
for (Result<Item> itemResult : items) {
Item item = itemResult.get();
minioClient.removeObject(
RemoveObjectArgs.builder().bucket(bucketName).object(item.objectName()).build()
);
}
} catch (Exception e) {
throw new RuntimeException("Error occurred while deleting folder", e);
}
}
}
控制器方法用于接受文件名列表并调用服务中的方法进行下载。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@RestController
public class FileDownloadController {
@Autowired
private MinioService minioService;
@GetMapping("/download-zip")
public void downloadZip(@RequestParam List<String> fileNames, HttpServletResponse response) {
minioService.downloadFolderAsZip(fileNames, response);
}
}
可以通过以下 GET 请求测试功能:
GET http://localhost:8080/download-zip?fileNames=file1.txt&fileNames=file2.jpg&fileNames=file3.pdf
SpringBoot+minio实现多文件下载时在minio指定的桶名下面生产一个文件夹,将需要下载放到这个文件夹中,并把这个文件夹打成一个压缩包后进行下载,下载成功后保留压缩包信息存放到数据库并且删除这个文件夹
要实现此功能,需要将多个文件上传到一个临时文件夹,并将该文件夹压缩为一个 ZIP 文件,供客户端下载。在下载成功后,将压缩包信息存储到数据库,并删除临时文件夹的所有文件。
以下是实现步骤和代码:
在 application.properties
中添加 MinIO 和数据库的配置:
# MinIO 配置
minio.url=http://localhost:9000
minio.accessKey=your-access-key
minio.secretKey=your-secret-key
minio.bucketName=your-bucket
# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/yourdb
spring.datasource.username=root
spring.datasource.password=yourpassword
spring.jpa.hibernate.ddl-auto=update
创建一个实体类 ZipFileRecord
来保存压缩包信息:
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
public class ZipFileRecord {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String fileName;
private String filePath;
private LocalDateTime createdTime;
// Getters and Setters
// ...
}
创建一个 ZipFileRecordRepository
,用于保存压缩包信息:
import org.springframework.data.jpa.repository.JpaRepository;
public interface ZipFileRecordRepository extends JpaRepository<ZipFileRecord, Long> {
}
编写服务类 MinioService
,完成文件夹创建、文件复制、打包下载、数据库保存和清理的逻辑。
import io.minio.*;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Service
public class MinioService {
@Autowired
private MinioClient minioClient;
@Autowired
private ZipFileRecordRepository zipFileRecordRepository;
@Value("${minio.bucketName}")
private String bucketName;
public void downloadFolderAsZip(List<String> fileNames, HttpServletResponse response) {
String tempFolderName = "temp-folder-" + UUID.randomUUID(); // 创建临时文件夹
String zipFileName = "download-" + UUID.randomUUID() + ".zip";
String zipFilePath = tempFolderName + "/" + zipFileName;
try {
// 复制文件到临时文件夹
for (String fileName : fileNames) {
String objectName = tempFolderName + "/" + fileName;
minioClient.copyObject(
CopyObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.source(bucketName + "/" + fileName)
.build()
);
}
// 设置响应头,下载压缩包
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=" + zipFileName);
// 创建 ZIP 输出流
try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
for (String fileName : fileNames) {
String objectName = tempFolderName + "/" + fileName;
// 获取每个文件的输入流
try (InputStream inputStream = minioClient.getObject(
GetObjectArgs.builder().bucket(bucketName).object(objectName).build())) {
// 写入 ZIP 条目
zipOut.putNextEntry(new ZipEntry(fileName));
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) >= 0) {
zipOut.write(buffer, 0, length);
}
zipOut.closeEntry(); // 结束条目写入
}
}
zipOut.finish(); // 完成 ZIP 文件
}
// 将 ZIP 文件信息保存到数据库
saveZipFileRecord(zipFileName, zipFilePath);
// 删除临时文件夹中的文件
deleteFolder(tempFolderName);
} catch (Exception e) {
throw new RuntimeException("Error occurred while downloading folder as zip", e);
}
}
// 保存 ZIP 文件信息到数据库
private void saveZipFileRecord(String zipFileName, String zipFilePath) {
ZipFileRecord record = new ZipFileRecord();
record.setFileName(zipFileName);
record.setFilePath(zipFilePath);
record.setCreatedTime(LocalDateTime.now());
zipFileRecordRepository.save(record);
}
// 删除指定文件夹及其内容
private void deleteFolder(String folderName) {
try {
Iterable<Result<Item>> items = minioClient.listObjects(
ListObjectsArgs.