SpringBoot集成MinIO8.0

一、安装MinIO

中文官网地址:https://www.minio.org.cn/download.shtml
官网地址:https://min.io/download
官网有相应的安装命令,可查看

建议引用相应版本的依赖
SpringBoot集成MinIO8.0_第1张图片

二、集成SpringBoot

1.引入依赖

<dependency>
    <groupId>io.miniogroupId>
    <artifactId>minioartifactId>
    <version>8.4.3version>
dependency>

2.配置文件

  # minio配置
  minio:
    endpoint: http://124.223.18.203:9000
    region:
    access-key: F5PKaRjxGXlbiFmarzF7
    secret-key: cKL8dQpLoORJ21Gw7882lUIAbA66RGKaKfsl0om2
    bucket: file

3.配置类

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 读取项目文件配置
 *
 * @author qiangesoft
 */
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {

    /**
     * 服务地址
     */
    private String endpoint = "http://127.0.0.1/9000/";

    /**
     * 地区
     */
    private String region;

    /**
     * 认证账户
     */
    private String accessKey;

    /**
     * 认证密码
     */
    private String secretKey;

    /**
     * 桶
     */
    private String bucket;

}

4.实例化客户端

import com.qiangesoft.rdp.starter.minio.core.MinioTemplate;
import com.qiangesoft.rdp.starter.minio.core.MinioTemplateImpl;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ObjectUtils;

/**
 * minio自动配置
 *
 * @author qiangesoft
 * @date 2023-09-15
 */
@Slf4j
@Configuration
@ConditionalOnClass(value = {MinioClient.class})
@RequiredArgsConstructor
@EnableConfigurationProperties(MinioProperties.class)
public class MinioConfiguration {

    private final MinioProperties minioProperties;

    @Bean
    @ConditionalOnMissingBean
    public MinioClient minioClient() {
        log.info("MinioClient initializing, url is {}, accessKey is {}!", minioProperties.getEndpoint(), minioProperties.getAccessKey());

        MinioClient.Builder builder = MinioClient
                .builder()
                .endpoint(minioProperties.getEndpoint())
                .credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey());
        String region = minioProperties.getRegion();
        if (region != null && region.length() > 0) {
            builder.region(region);
        }
        MinioClient minioClient = builder.build();

        String bucket = minioProperties.getBucket();
        if (ObjectUtils.isEmpty(bucket)) {
            log.error("Bucket not empty");
            throw new RuntimeException("Bucket not empty");
        }

        // 初始化桶
        if (!this.checkExists(minioClient, bucket)) {
            this.createBucket(minioClient, bucket);
        }

        log.info("MinioClient initialization success!");
        return minioClient;
    }

    @Bean
    @ConditionalOnMissingBean
    public MinioTemplate minioTemplate() {
        return new MinioTemplateImpl(minioProperties, minioClient());
    }

    /**
     * 检查桶是否存在
     *
     * @param minioClient
     * @param bucketName
     * @return
     */
    private boolean checkExists(MinioClient minioClient, String bucketName) {
        try {
            return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            log.error("Check bucket exists failed with error");
            throw new RuntimeException("Check bucket exists failed with error");
        }
    }

    /**
     * 创建桶
     *
     * @param minioClient
     * @param bucketName
     */
    private void createBucket(MinioClient minioClient, String bucketName) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            log.error("Create bucket failed with error");
            throw new RuntimeException("Create bucket failed with error");
        }
    }
}

5.API使用

import io.minio.StatObjectResponse;
import io.minio.messages.Bucket;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.List;

/**
 * minio文件服务
 *
 * @author qiangesoft
 * @date 2023-04-21
 */
public interface MinioTemplate {

    /**
     * 创建桶
     *
     * @param bucketName
     * @throws Exception
     */
    void createBucket(String bucketName) throws Exception;

    /**
     * 获取桶
     *
     * @return
     */
    List<Bucket> listBuckets() throws Exception;

    /**
     * 获取桶
     *
     * @param bucketName
     * @return
     * @throws Exception
     */
    Bucket getBucket(String bucketName) throws Exception;

    /**
     * 删除桶
     *
     * @param bucketName
     * @throws Exception
     */
    void removeBucket(String bucketName) throws Exception;

    /**
     * 上传文件
     *
     * @param bucketName
     * @param inputStream
     * @param objectName
     * @return
     * @throws Exception
     */
    String putObject(String bucketName, InputStream inputStream, String objectName) throws Exception;

    /**
     * 上传文件
     *
     * @param bucketName
     * @param file
     * @return
     * @throws Exception
     */
    String putObject(String bucketName, MultipartFile file) throws Exception;

    /**
     * 分享文件地址
     *
     * @param bucketName
     * @param objectName
     * @param expires
     * @return
     * @throws Exception
     */
    String getObjectURL(String bucketName, String objectName, Integer expires) throws Exception;

    /**
     * 获取文件
     *
     * @param bucketName
     * @param objectName
     * @return
     * @throws Exception
     */
    InputStream getObject(String bucketName, String objectName) throws Exception;

    /**
     * 获取文件
     *
     * @param bucketName
     * @param objectName
     * @return
     * @throws Exception
     */
    StatObjectResponse getObjectInfo(String bucketName, String objectName) throws Exception;

    /**
     * 下载文件
     *
     * @param bucketName
     * @param filename
     * @param response
     * @throws Exception
     */
    void download(String bucketName, String filename, HttpServletResponse response) throws Exception;

    /**
     * 删除文件
     *
     * @param bucketName
     * @param objectName
     * @throws Exception
     */
    void removeObject(String bucketName, String objectName) throws Exception;

    /**
     * 删除文件
     *
     * @param bucketName
     * @param objectNames
     * @throws Exception
     */
    void removeObjects(String bucketName, List<String> objectNames) throws Exception;
}
import com.qiangesoft.rdp.starter.minio.config.MinioProperties;
import io.minio.*;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * minio文件服务实现类
 *
 * @author qiangesoft
 * @date 2023-04-21
 */
@Slf4j
public class MinioTemplateImpl implements MinioTemplate {

    private static final String SLASH = "/";

    private MinioProperties minioProperties;

    private MinioClient minioClient;

    public MinioTemplateImpl(MinioProperties minioProperties, MinioClient minioClient) {
        this.minioProperties = minioProperties;
        this.minioClient = minioClient;
    }

    @Override
    public void createBucket(String bucketName) throws Exception {
        BucketExistsArgs args = BucketExistsArgs.builder().bucket(bucketName).build();
        boolean exists = minioClient.bucketExists(args);
        if (!exists) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }
    }

    @Override
    public List<Bucket> listBuckets() throws Exception {
        return minioClient.listBuckets();
    }

    @Override
    public Bucket getBucket(String bucketName) throws Exception {
        Optional<Bucket> first = this.listBuckets().stream().filter(e -> e.name().equals(bucketName)).findFirst();
        return first.orElse(null);
    }

    @Override
    public void removeBucket(String bucketName) throws Exception {
        minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
    }

    @Override
    public String putObject(String bucketName, InputStream inputStream, String objectName) throws Exception {
        // 参数校验
        Assert.notNull(bucketName, "bucketName is not blank");
        Assert.notNull(inputStream, "inputStream is not null");
        Assert.notNull(objectName, "objectName is not blank");

        // 判断存储桶是否存在,不存在则创建
        this.createBucket(bucketName);

        // 上传
        minioClient.putObject(
                PutObjectArgs.builder().bucket(bucketName).object(objectName)
                        .stream(inputStream, inputStream.available(), -1)
                        .contentType("application/octet-stream")
                        .build());
        return bucketName + SLASH + objectName;
    }

    @Override
    public String putObject(String bucketName, MultipartFile file) throws Exception {
        // 参数校验
        Assert.notNull(bucketName, "bucketName is not blank");
        Assert.notNull(file, "file is not null");

        // 判断存储桶是否存在  不存在则创建
        createBucket(bucketName);

        // 文件名
        String objectName = file.getOriginalFilename();

        // 上传
        minioClient.putObject(
                PutObjectArgs.builder().bucket(bucketName).object(objectName)
                        .stream(file.getInputStream(), file.getSize(), -1)
                        .contentType(file.getContentType())
                        .build());
        return bucketName + SLASH + objectName;
    }

    @Override
    public String getObjectURL(String bucketName, String objectName, Integer expires) throws Exception {
        return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).expiry(expires).build());
    }

    @Override
    public InputStream getObject(String bucketName, String objectName) throws Exception {
        return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }

    @Override
    public StatObjectResponse getObjectInfo(String bucketName, String objectName) throws Exception {
        return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }

    @Override
    public void download(String bucketName, String filename, HttpServletResponse response) throws Exception {
        GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName).object(filename).build();
        GetObjectResponse objectResponse = minioClient.getObject(objectArgs);
        byte[] buf = new byte[1024];
        int len;
        try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {
            while ((len = objectResponse.read(buf)) != -1) {
                os.write(buf, 0, len);
            }
            os.flush();
            byte[] bytes = os.toByteArray();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/force-download");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.addHeader("Content-Disposition", "attachment;fileName=" + filename);
            try (ServletOutputStream stream = response.getOutputStream()) {
                stream.write(bytes);
                stream.flush();
            }
        }
    }

    @Override
    public void removeObject(String bucketName, String objectName) throws Exception {
        minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }

    @Override
    public void removeObjects(String bucketName, List<String> objectNames) throws Exception {
        List<DeleteObject> deleteObjectList = new ArrayList<>();
        for (String objectName : objectNames) {
            DeleteObject deleteObject = new DeleteObject(objectName);
            deleteObjectList.add(deleteObject);
        }
        Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(deleteObjectList).build());
        for (Result<DeleteError> result : results) {
            DeleteError error = result.get();
            log.error("Error in deleting object " + error.objectName() + "; " + error.message());
        }
    }
}

另有启动器版本

点击跳转

你可能感兴趣的:(Spring系列,spring,boot,minio)