Spring Boot整合MinIO对象存储教程

发布于:2025-03-07 ⋅ 阅读:(59) ⋅ 点赞:(0)

精心整理了最新的面试资料和简历模板,有需要的可以自行获取

点击前往百度网盘获取
点击前往夸克网盘获取

以下是一份详细的Spring Boot整合MinIO的教程,包含基础配置和常用文件操作示例:


Spring Boot整合MinIO对象存储教程

一、MinIO简介

MinIO是一款高性能、云原生的分布式对象存储系统,兼容Amazon S3 API。适用于存储图片、文档、视频等非结构化数据。

二、环境准备

  1. 安装MinIO服务(推荐Docker方式)
docker run -d \
  -p 9000:9000 \
  -p 9001:9001 \
  --name minio \
  -v /mnt/data:/data \
  -e "MINIO_ROOT_USER=admin" \
  -e "MINIO_ROOT_PASSWORD=admin123" \
  quay.io/minio/minio server /data --console-address ":9001"
  1. 访问控制台:http://localhost:9001 使用admin/admin123登录

三、创建Spring Boot项目

  1. 使用Spring Initializr创建项目
  • 依赖选择:Spring Web、Lombok
  1. 添加MinIO依赖(pom.xml)
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.5.7</version>
</dependency>

四、配置MinIO参数

application.yml:

minio:
  endpoint: http://localhost:9000
  access-key: admin
  secret-key: admin123
  bucket-name: mybucket
  secure: false  # 是否使用https

配置类MinioConfig.java:

@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
    private String endpoint;
    private String accessKey;
    private String secretKey;
    private String bucketName;
    private Boolean secure;

    @Bean
    public MinioClient minioClient() {
        return MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .secure(secure)
                .build();
    }
}

五、实现MinIO工具类

MinioUtils.java:

@Slf4j
@Component
@RequiredArgsConstructor
public class MinioUtils {
    private final MinioClient minioClient;
    private final MinioConfig minioConfig;

    /**
     * 初始化存储桶
     */
    public void createBucket() throws Exception {
        boolean found = minioClient.bucketExists(BucketExistsArgs.builder()
                .bucket(minioConfig.getBucketName())
                .build());
        
        if (!found) {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .build());
        }
    }

    /**
     * 文件上传
     */
    public String uploadFile(MultipartFile file, String objectName) throws Exception {
        if (file.isEmpty()) {
            throw new RuntimeException("上传文件不能为空");
        }
        
        createBucket(); // 确保存储桶存在
        
        minioClient.putObject(
                PutObjectArgs.builder()
                        .bucket(minioConfig.getBucketName())
                        .object(objectName)
                        .stream(file.getInputStream(), file.getSize(), -1)
                        .contentType(file.getContentType())
                        .build());
        
        return minioConfig.getEndpoint() + "/" + minioConfig.getBucketName() + "/" + objectName;
    }

    /**
     * 文件下载
     */
    public InputStream downloadFile(String objectName) throws Exception {
        return minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(minioConfig.getBucketName())
                        .object(objectName)
                        .build());
    }

    /**
     * 删除文件
     */
    public void deleteFile(String objectName) throws Exception {
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(minioConfig.getBucketName())
                        .object(objectName)
                        .build());
    }

    /**
     * 获取文件列表
     */
    public List<String> listFiles() throws Exception {
        List<String> list = new ArrayList<>();
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder()
                        .bucket(minioConfig.getBucketName())
                        .build());
        
        for (Result<Item> result : results) {
            Item item = result.get();
            list.add(item.objectName());
        }
        return list;
    }
}

六、创建文件控制器

FileController.java:

@RestController
@RequestMapping("/file")
@RequiredArgsConstructor
public class FileController {
    private final MinioUtils minioUtils;

    @PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            return "上传失败,请选择文件";
        }
        String objectName = UUID.randomUUID() + "-" + file.getOriginalFilename();
        return minioUtils.uploadFile(file, objectName);
    }

    @GetMapping("/download")
    public ResponseEntity<InputStreamResource> download(@RequestParam String fileName) throws Exception {
        InputStream inputStream = minioUtils.downloadFile(fileName);
        return ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .header(HttpHeaders.CONTENT_DISPOSITION, 
                        "attachment; filename=\"" + fileName + "\"")
                .body(new InputStreamResource(inputStream));
    }

    @DeleteMapping("/delete")
    public String delete(@RequestParam String fileName) throws Exception {
        minioUtils.deleteFile(fileName);
        return "删除成功";
    }

    @GetMapping("/list")
    public List<String> listFiles() throws Exception {
        return minioUtils.listFiles();
    }
}

七、测试验证

  1. 上传文件测试(使用Postman):

    • POST /file/upload
    • 选择form-data格式,key为"file"
  2. 下载文件测试:

    • GET /file/download?fileName={文件名}
  3. 文件列表查询:

    • GET /file/list

八、常见问题处理

  1. 连接失败检查:

    • 确认MinIO服务状态
    • 检查endpoint地址和端口
    • 验证access-key/secret-key是否正确
  2. 存储桶权限问题:

    • 在MinIO控制台设置存储桶访问策略
    • 或通过SDK设置策略:
    minioClient.setBucketPolicy(SetBucketPolicyArgs.builder()
            .bucket(bucketName)
            .config(policyJson)
            .build());
    
  3. 大文件上传:

    • 使用分片上传(multipart upload)
    • 调整客户端超时时间

九、扩展功能建议

  1. 添加文件预览功能
  2. 实现文件秒传(MD5校验)
  3. 集成Spring Security进行权限控制
  4. 添加文件分享链接(预签名URL)

整合完成后,你的Spring Boot应用即可实现完整的文件存储管理功能。建议在实际生产环境中:

  1. 使用HTTPS连接
  2. 配置合理的存储桶策略
  3. 定期进行存储桶维护
  4. 监控存储空间使用情况