springboot集成minio

该文章介绍了如何在SpringBoot项目中集成Minio进行文件存储。首先,文章列出了引入Minio和Okhttp的POM依赖,并注意排除冲突。接着,展示了配置类`MinioConfig`,用于设置Minio客户端、创建和检查桶以及设置桶策略。然后,提供了YAML配置文件,包括静态资源路径、文件上传限制和Jackson序列化设置。此外,文章还包含了一个`MinioUtils`工具类,包含了上传文件、检查文件或桶存在性、删除文件等方法。最后,提到了一个用于表示上传文件结果的`UploadFileResult`类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、引入POM依赖

<!-- Minio -->
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.4.3</version>
    <exclusions>
        <exclusion>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.9.0</version>
</dependency>

注意:8.4.3需要排除okhttp在引入版本高的okhttp否者启动会报错。

二、配置类


import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.SetBucketPolicyArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * Minio 配置信息
 *
 * @author zero
 */
@Component
@Slf4j
public class MinioConfig {
    @Value("${zero.minio.bucketName}")
    private String bucketName;

    @Bean
    public MinioClient getMinioClient() {
        MinioClient minioClient = MinioClient.builder()
                .endpoint(minio.getEndpoint())
                .credentials(minio.getAccessKey(), minio.getSecretKey())
                .build();
        try {
            boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!bucketExists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                // Define the policy string
                String policy = "{\n" +
                        "    \"Version\": \"2012-10-17\",\n" +
                        "    \"Statement\": [\n" +
                        "        {\n" +
                        "            \"Action\": [\n" +
                        "                \"s3:GetObject\"\n" +
                        "            ],\n" +
                        "            \"Effect\": \"Allow\",\n" +
                        "            \"Principal\": {\n" +
                        "                \"AWS\": [\n" +
                        "                    \"*\"\n" +
                        "                ]\n" +
                        "            },\n" +
                        "            \"Resource\": [\n" +
                        "                \"arn:aws:s3:::" + bucketName + "/*\"\n" +
                        "            ]\n" +
                        "        }\n" +
                        "    ]\n" +
                        "}";
                // Set the bucket policy
                minioClient.setBucketPolicy(
                        SetBucketPolicyArgs.builder()
                                .bucket(bucketName)
                                .config(policy)
                                .build());
            }
        } catch (Exception e) {
            log.error("创建桶失败!", e);
            throw new RuntimeException("创建桶失败!");
        }

        return minioClient;
    }
}

三、YAML配置文件

spring:
  resources:
    static-locations: ${zero.minio.endpoint}/${zero.minio.bucketName}
  servlet:
    multipart:
      enabled: true #开启文件上传
      max-file-size: 100MB #单个文件大小
      max-request-size: 100MB #总上传的数据大小
  jackson:
    # json 序列化排除值为 null 的属性
    default-property-inclusion: non_null
    # 配置 Date 类的时间格式
    date-format: yyyy-MM-dd HH:mm:ss
    # 配置 Date 类的时区
    time-zone: GMT+8
zero:
  minio:
    endpoint: http://127.0.0.1:9000
    accessKey: admin
    secretKey: admin
    bucketName: test

四、工具类MinioUtils


import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * Minio工具类
 *
 * @author zero
 */
@Component
@Slf4j
public class MinioUtils {

    @Resource
    private MinioClient minioClient;

    /**
     * 判断桶是否存在
     *
     * @param bucketName bucket名称
     * @return true存在,false不存在
     */
    public boolean bucketExists(String bucketName) {
        try {
            return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            log.error("检查桶是否存在失败!", e);
            throw new RuntimeException("检查桶是否存在失败!");
        }
    }

    /**
     * 创建bucket
     *
     * @param bucketName bucket名称
     */
    public void createBucket(String bucketName) {
        if (!this.bucketExists(bucketName)) {
            try {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            } catch (Exception e) {
                log.error("创建桶失败!", e);
            throw new RuntimeException("创建桶失败!");
            }
        }
    }

    /**
     * 上传MultipartFile文件到全局默认文件桶中
     *
     * @param bucketName 桶
     * @param catalog    文件夹
     * @param file       文件
     * @return 文件对应的URL
     */
    public UploadFileResult putObject(String bucketName, String catalog, MultipartFile file) {
        // 给文件名添加时间戳防止重复
        String originalFilename = file.getOriginalFilename();
        String fileName = getFileName(Objects.requireNonNull(originalFilename));
        // 开始上传
        String objectName = this.buildObject(catalog, fileName);
        try (InputStream stream = file.getInputStream();) {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .