栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【工具篇】Spring Boot 整合 Minio OSS 存储服务

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【工具篇】Spring Boot 整合 Minio OSS 存储服务

写在最前
  • Docker安装MinIO
Spring Boot 整合 Minio

Demo 地址:mingyue-springboot-minio

1.添加依赖


    io.minio
    minio
    8.3.9



    com.squareup.okhttp3
    okhttp
    4.9.0

2.修改配置文件
minio:
  endpoint: http://IP:9000
  port: 9000
  accessKey: 登录账号
  secretKey: 登录密码
  secure: false
  bucket-name: mingyue-test # 桶名
  image-size: 10485760 # 图片文件的最大大小
  file-size: 1073741824 # 文件的最大大小
3.创建 Minio 配置类
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;


@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioPropertiesConfig {
  
  private String endpoint;

  
  private Integer port;

  
  private String accessKey;

  
  private String secretKey;

  
  private boolean secure;

  
  private String bucketName;

  
  private long imageSize;

  
  private long fileSize;

  
  @Bean
  public MinioClient minioClient() {
    return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
  }
}
4.创建 Minio 工具类
import com.csp.mingyue.minio.config.MinioPropertiesConfig;
import io.minio.BucketExistsArgs;
import io.minio.GetObjectArgs;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.ListObjectsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveBucketArgs;
import io.minio.RemoveObjectArgs;
import io.minio.RemoveObjectsArgs;
import io.minio.Result;
import io.minio.StatObjectArgs;
import io.minio.StatObjectResponse;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;


@Slf4j
@Component
@RequiredArgsConstructor
public class MinioUtil {

  private final MinioPropertiesConfig minioPropertiesConfig;

  private final MinioClient minioClient;

  
  @SneakyThrows
  public boolean bucketExists(String bucketName) {
    boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
    if (found) {
      log.info("{} exists", bucketName);
    } else {
      log.info("{} does not exist", bucketName);
    }
    return found;
  }

  
  @SneakyThrows
  public boolean makeBucket(String bucketName) {
    boolean flag = bucketExists(bucketName);
    if (!flag) {
      minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
      return true;
    } else {
      return false;
    }
  }

  
  @SneakyThrows
  public List listBucketNames() {
    List bucketList = listBuckets();
    List bucketListName = new ArrayList<>();
    for (Bucket bucket : bucketList) {
      bucketListName.add(bucket.name());
    }
    return bucketListName;
  }

  
  @SneakyThrows
  public List listBuckets() {
    return minioClient.listBuckets();
  }

  
  @SneakyThrows
  public boolean removeBucket(String bucketName) {
    boolean flag = bucketExists(bucketName);
    if (flag) {
      Iterable> myObjects = listObjects(bucketName);
      for (Result result : myObjects) {
        Item item = result.get();
        // 有对象文件,则删除失败
        if (item.size() > 0) {
          return false;
        }
      }
      // 删除存储桶,注意,只有存储桶为空时才能删除成功。
      minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
      flag = bucketExists(bucketName);
      return !flag;
    }
    return false;
  }

  
  @SneakyThrows
  public List listObjectNames(String bucketName) {
    List listObjectNames = new ArrayList<>();
    boolean flag = bucketExists(bucketName);
    if (flag) {
      Iterable> myObjects = listObjects(bucketName);
      for (Result result : myObjects) {
        Item item = result.get();
        listObjectNames.add(item.objectName());
      }
    } else {
      listObjectNames.add("存储桶不存在");
    }
    return listObjectNames;
  }

  
  @SneakyThrows
  public Iterable> listObjects(String bucketName) {
    boolean flag = bucketExists(bucketName);
    if (flag) {
      return minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());
    }
    return null;
  }

  
  @SneakyThrows
  public void putObject(
      String bucketName, MultipartFile multipartFile, String filename, String fileType) {
    InputStream inputStream = new ByteArrayInputStream(multipartFile.getBytes());
    minioClient.putObject(
        PutObjectArgs.builder().bucket(bucketName).object(filename).stream(
                inputStream, -1, minioPropertiesConfig.getFileSize())
            .contentType(fileType)
            .build());
  }

  
  @SneakyThrows
  public String getObjectUrl(String bucketName, String objectName) {
    boolean flag = bucketExists(bucketName);
    String url = "";
    if (flag) {
      url =
          minioClient.getPresignedObjectUrl(
              GetPresignedObjectUrlArgs.builder()
                  .method(Method.GET)
                  .bucket(bucketName)
                  .object(objectName)
                  .expiry(2, TimeUnit.MINUTES)
                  .build());
      log.info("url:{}", url);
    }
    return url;
  }

  
  @SneakyThrows
  public boolean removeObject(String bucketName, String objectName) {
    boolean flag = bucketExists(bucketName);
    if (flag) {
      minioClient.removeObject(
          RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
      return true;
    }
    return false;
  }

  
  @SneakyThrows
  public InputStream getObject(String bucketName, String objectName) {
    boolean flag = bucketExists(bucketName);
    if (flag) {
      StatObjectResponse statObject = statObject(bucketName, objectName);
      if (statObject != null && statObject.size() > 0) {
        return minioClient.getObject(
            GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
      }
    }
    return null;
  }

  
  @SneakyThrows
  public StatObjectResponse statObject(String bucketName, String objectName) {
    boolean flag = bucketExists(bucketName);
    if (flag) {
      return minioClient.statObject(
          StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }
    return null;
  }

  
  @SneakyThrows
  public boolean removeObject(String bucketName, List objectNames) {
    boolean flag = bucketExists(bucketName);
    if (flag) {
      List objects = new LinkedList<>();
      for (String objectName : objectNames) {
        objects.add(new DeleteObject(objectName));
      }
      Iterable> results =
          minioClient.removeObjects(
              RemoveObjectsArgs.builder().bucket(bucketName).objects(objects).build());
      for (Result result : results) {
        DeleteError error = result.get();
        log.info("Error in deleting object {}: {}", error.objectName(), error.message());
      }
    }
    return true;
  }

  
  @SneakyThrows
  public InputStream getObject(String bucketName, String objectName, long offset, Long length) {
    boolean flag = bucketExists(bucketName);
    if (flag) {
      StatObjectResponse statObject = statObject(bucketName, objectName);
      if (statObject != null && statObject.size() > 0) {
        return minioClient.getObject(
            GetObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .offset(offset)
                .length(length)
                .build());
      }
    }
    return null;
  }

  
  @SneakyThrows
  public boolean putObject(
      String bucketName, String objectName, InputStream inputStream, String contentType) {
    boolean flag = bucketExists(bucketName);
    if (flag) {
      minioClient.putObject(
          PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(
                  inputStream, -1, minioPropertiesConfig.getFileSize())
              .contentType(contentType)
              .build());
      StatObjectResponse statObject = statObject(bucketName, objectName);
      return statObject != null && statObject.size() > 0;
    }
    return false;
  }
}
5.创建 Minio Service
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.csp.mingyue.minio.config.MinioPropertiesConfig;
import com.csp.mingyue.minio.util.MinioUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


@Slf4j
@Service
@RequiredArgsConstructor
public class MinioService {

  private final MinioPropertiesConfig minioPropertiesConfig;

  private final MinioUtil minioUtil;

  
  public boolean bucketExists(String bucketName) {
    return minioUtil.bucketExists(bucketName);
  }

  
  public void makeBucket(String bucketName) {
    minioUtil.makeBucket(bucketName);
  }

  
  public String upload(MultipartFile file, String bucketName, String fileType) {
    if (StrUtil.isBlank(bucketName)) {
      log.info("bucketName is null");
    }

    try {
      if (!this.bucketExists(bucketName)) {
        this.makeBucket(bucketName);
      }
      String fileName = file.getOriginalFilename();

      assert fileName != null;
      String objectName =
          IdUtil.randomUUID().replace("-", "") + fileName.substring(fileName.lastIndexOf("."));
      minioUtil.putObject(bucketName, file, objectName, fileType);
      return minioPropertiesConfig.getEndpoint() + "/" + bucketName + "/" + objectName;
    } catch (Exception e) {
      e.printStackTrace();
      return "上传失败";
    }
  }

  
  public String getObjectUrl(String bucketName, String objectName) {
    return minioUtil.getObjectUrl(bucketName, objectName);
  }
}
6.Minio 接口
import com.csp.mingyue.minio.config.MinioPropertiesConfig;
import com.csp.mingyue.minio.service.MinioService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;


@RestController
@RequestMapping("/minio")
@RequiredArgsConstructor
public class MinioController {

  private final MinioPropertiesConfig minioPropertiesConfig;

  private final MinioService minioService;

  @PostMapping("/upload")
  public String upload(@RequestParam(name = "multipartFile") MultipartFile multipartFile) {
    return minioService.upload(
        multipartFile, minioPropertiesConfig.getBucketName(), multipartFile.getContentType());
  }

  @GetMapping("/getObjectUrl")
  public String getObjectUrl(String objectName) {
    return minioService.getObjectUrl(minioPropertiesConfig.getBucketName(), objectName);
  }
}
7.测试接口
  • Post http://127.0.0.1:8080/minio/upload 上传接口

    接口返回如下:

    http://ip:port/mingyue-test/60396cc92fec4e2cbb4a974d810e7115.jpg
    
  • Get http://127.0.0.1:8080/minio/getObjectUrl?objectName=60396cc92fec4e2cbb4a974d810e7115.jpg 查询接口

    接口返回如下:

    http://ip:port/mingyue-test/60396cc92fec4e2cbb4a974d810e7115.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20220425%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220425T055235Z&X-Amz-Expires=120&X-Amz-SignedHeaders=host&X-Amz-Signature=35eeffddca22f8211a1af0e936066e848a988e82b73548cfc87f2294e0861f01
    
补充说明

只写了两个接口,想要查询桶列表或者其他功能具体看 MinioUtil 函数,主要可以参考如下文档:

  • Minio中文文档
  • MINIO 对象存储祼机使用文档
  • Minio快速入门指南
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/837150.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号