SpringBoot 整合 MinIO

2022-04-25 14:14:03

官方文档

下载安装

下载地址:🔗

Windows

https://dl.min.io/server/minio/release/windows-amd64/minio.exe

Linux

wget http://dl.minio.org.cn/server/minio/release/linux-amd64/minio

MacOS

brewinstall minio/stable/minio

运行

Windows

D:\MinIO>minio.exe server ./data

Windows

Linux(后台启动)

chmod +x miniocd /home/minio

./minio server --console-address"0.0.0.0:9100" /home/minio/data> /home/minio/minio.log2>&1&

MacOS

minio server /data

登录界面

修改用户名密码

export MINIO_ROOT_USER= rootexport MINIO_ROOT_PASSWORD=88888888

创建存储桶

创建存储桶(一)
创建存储桶(二)
创建存储桶(三)

修改访问权限

  1. 进入存储桶(Buckets)
  2. 点击Manage
  3. 修改Access Policypublic

修改访问权限(一)
修改访问权限(二)
修改访问权限(三)

Spring Boot 整合 MinIO

添加Maven依赖

<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.3.6</version></dependency>

解决依赖冲突

使用minio8.3.6版本的依赖,报下列异常:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    io.minio.S3Base.<clinit>(S3Base.java:105)

The following method did not exist:

    okhttp3.RequestBody.create([BLokhttp3/MediaType;)Lokhttp3/RequestBody;

The method's class, okhttp3.RequestBody, is available from the following locations:

    jar:file:/D:/repository/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar!/okhttp3/RequestBody.class

The class hierarchy was loaded from the following locations:

    okhttp3.RequestBody: file:/D:/repository/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar


Action:

Correct the classpath of your application so that it contains a single, compatible version of okhttp3.RequestBody

注意:由于okhttp3依赖冲突,默认的版本低于minio所需版本,会导致启动失败,可通过以下方法解决:

  1. 降低MinIO版本
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.2.1</version></dependency>
  1. 引入高版本的okhttp依赖
<dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.9.3</version></dependency>

配置application.yml文件

# MinIO配置minio:# 服务地址endpoint: http://127.0.0.1:9000# 文件地址fileHost: http://127.0.0.1:9000# 存储桶名称bucket: starimmortal# 用户名access-key: minioadmin# 密码secret-key: minioadmin

工具类

importio.minio.*;importio.minio.http.Method;importio.minio.messages.Bucket;importio.minio.messages.Item;importlombok.extern.slf4j.Slf4j;importorg.springframework.stereotype.Component;importorg.springframework.web.multipart.MultipartFile;importjava.io.ByteArrayInputStream;importjava.io.InputStream;importjava.io.UnsupportedEncodingException;importjava.net.URLDecoder;importjava.util.ArrayList;importjava.util.List;importjava.util.Optional;/**
 * MinIO工具类
 *
 * @author william@StarImmortal
 * @date 2022/04/19
 */@Component@Slf4jpublicclassMinioUtil{/**
     * MinioClient实例
     */privatestaticMinioClient minioClient;/**
     * Bucket所在地域对应的Endpoint
     */privatestaticString endpoint;/**
     * 存储桶名称
     */privatestaticString bucketName;/**
     * 用户名
     */privatestaticString accessKey;/**
     * 密码
     */privatestaticString secretKey;/**
     * 分隔符
     */privatestaticfinalString SEPARATOR="/";publicMinioUtil(){}publicMinioUtil(String endpoint,String bucketName,String accessKey,String secretKey){MinioUtil.endpoint= endpoint;MinioUtil.bucketName= bucketName;MinioUtil.accessKey= accessKey;MinioUtil.secretKey= secretKey;this.initMinioClient();}/**
     * 创建基于Java端的MinioClient
     */publicvoidinitMinioClient(){try{if(null== minioClient){
                log.info("开始创建MinioClient...");
                minioClient=MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();createBucket(bucketName);
                log.info("MinioClient创建完毕...");}}catch(Exception e){
            log.error("MinIO服务器异常:{0}", e);}}/**
     * 获取上传文件前缀路径
     *
     * @return 前缀路径
     */publicstaticStringgetBasisUrl(){return endpoint+ SEPARATOR+ bucketName+ SEPARATOR;}/******************************  Operate Bucket Start  ******************************//**
     * 启动SpringBoot容器的时候初始化Bucket,如果没有Bucket则创建
     */privatestaticvoidcreateBucket(String bucketName)throwsException{if(!bucketExists(bucketName)){
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());}}/**
     * 判断Bucket是否存在
     *
     * @return true:存在,false:不存在
     */publicstaticbooleanbucketExists(String bucketName)throwsException{return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());}/**
     * 获得Bucket策略
     *
     * @param bucketName 存储桶名称
     * @return Bucket策略
     */publicstaticStringgetBucketPolicy(String bucketName)throwsException{return minioClient.getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketName).build());}/**
     * 获得所有Bucket列表
     *
     * @return Bucket列表
     */publicstaticList<Bucket>getAllBuckets()throwsException{return minioClient.listBuckets();}/**
     * 根据存储桶名称获取其相关信息
     *
     * @param bucketName 存储桶名称
     * @return 相关信息
     */publicstaticOptional<Bucket>getBucket(String bucketName)throwsException{returngetAllBuckets().stream().filter(b-> b.name().equals(bucketName)).findFirst();}/**
     * 根据存储桶名称删除Bucket,true:删除成功;false:删除失败,文件或已不存在
     *
     * @param bucketName 存储桶名称
     */publicstaticvoidremoveBucket(String bucketName)throwsException{
        minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());}/******************************  Operate Bucket End  ******************************//******************************  Operate Files Start  ******************************//**
     * 判断文件是否存在
     *
     * @param bucketName 存储桶名称
     * @param objectName 文件名
     * @return true:存在;false:不存在
     */publicstaticbooleanisObjectExist(String bucketName,String objectName){boolean exist=true;try{
            minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());}catch(Exception e){
            exist=false;}return exist;}/**
     * 判断文件夹是否存在
     *
     * @param bucketName 存储桶名称
     * @param objectName 文件夹名称
     * @return true:存在;false:不存在
     */publicstaticbooleanisFolderExist(String bucketName,String objectName){boolean exist=false;try{Iterable<Result<Item>> results= minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(false).build());for(Result<Item> result: results){Item item= result.get();if(item.isDir()&& objectName.equals(item.objectName())){
                    exist=true;}}}catch(Exception e){
            exist=false;}return exist;}/**
     * 根据文件前缀查询文件
     *
     * @param bucketName 存储桶名称
     * @param prefix     前缀
     * @param recursive  是否使用递归查询
     * @return MinioItem列表
     */publicstaticList<Item>getAllObjectsByPrefix(String bucketName,String prefix,boolean recursive)throwsException{List<Item> list=newArrayList<>();Iterable<Result<Item>> objectsIterator= minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());if(objectsIterator!=null){for(Result<Item> o: objectsIterator){Item item= o.get();
                list.add(item);}}return list;}/**
     * 获取文件流
     *
     * @param bucketName 存储桶名称
     * @param objectName 文件名
     * @return 二进制流
     */publicstaticInputStreamgetObject(String bucketName,String objectName)throwsException{return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());}/**
     * 断点下载
     *
     * @param bucketName 存储桶名称
     * @param objectName 文件名称
     * @param offset     起始字节的位置
     * @param length     要读取的长度
     * @return 二进制流
     */publicInputStreamgetObject(String bucketName,String objectName,long offset,long length)throwsException{return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).offset(offset).length(length).build());}/**
     * 获取路径下文件列表
     *
     * @param bucketName 存储桶名称
     * @param prefix     文件名称
     * @param recursive  是否递归查找,false:模拟文件夹结构查找
     * @return 二进制流
     */publicstaticIterable<Result<Item>>listObjects(String bucketName,String prefix,boolean recursive){return minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());}/**
     * 使用MultipartFile进行文件上传
     *
     * @param bucketName  存储桶名称
     * @param file        文件名
     * @param objectName  对象名
     * @param contentType 类型
     * @return ObjectWriteResponse对象
     */publicstaticObjectWriteResponseuploadFile(String bucketName,MultipartFile file,String objectName,String contentType)throwsException{InputStream inputStream= file.getInputStream();return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).contentType(contentType).stream(inputStream, inputStream.available(),-1).build());}/**
     * 上传本地文件
     *
     * @param bucketName 存储桶名称
     * @param objectName 对象名称
     * @param fileName   本地文件路径
     */publicstaticObjectWriteResponseuploadFile(String bucketName,String objectName,String fileName)throwsException{return minioClient.uploadObject(UploadObjectArgs.builder().bucket(bucketName).object(objectName).filename(fileName).build());}/**
     * 通过流上传文件
     *
     * @param bucketName  存储桶名称
     * @param objectName  文件对象
     * @param inputStream 文件流
     */publicstaticObjectWriteResponseuploadFile(String bucketName,String objectName,InputStream inputStream)throwsException{return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(inputStream, inputStream.available(),-1).build());}/**
     * 创建文件夹或目录
     *
     * @param bucketName 存储桶名称
     * @param objectName 目录路径
     */publicstaticObjectWriteResponsecreateDir(String bucketName,String objectName)throwsException{return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(newByteArrayInputStream(newbyte[]{}),0,-1).build());}/**
     * 获取文件信息, 如果抛出异常则说明文件不存在
     *
     * @param bucketName 存储桶名称
     * @param objectName 文件名称
     */publicstaticStringgetFileStatusInfo(String bucketName,String objectName)throwsException{return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build()).toString();}/**
     * 拷贝文件
     *
     * @param bucketName    存储桶名称
     * @param objectName    文件名
     * @param srcBucketName 目标存储桶
     * @param srcObjectName 目标文件名
     */publicstaticObjectWriteResponsecopyFile(String bucketName,String objectName,String srcBucketName,String srcObjectName)throwsException{return minioClient.copyObject(CopyObjectArgs.builder().source(CopySource.builder().bucket(bucketName).object(objectName).build()).bucket(srcBucketName).object(srcObjectName).build());}/**
     * 删除文件
     *
     * @param bucketName 存储桶名称
     * @param objectName 文件名称
     */publicstaticvoidremoveFile(String bucketName
  • 作者:人人都在发奋
  • 原文链接:https://blog.csdn.net/qq991658923/article/details/124623495
    更新时间:2022-04-25 14:14:03