SpringBoot整合Minio的详细步骤

这篇具有很好参考价值的文章主要介绍了SpringBoot整合Minio的详细步骤。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

小伙伴们好,欢迎关注,一起学习,无限进步

minio 是对象存储服务。它基于 Apache License 开源协议,兼容 Amazon S3 云存储接口。适合存储非结构化数据,如图片,音频,视频,日志等。对象文件最大可以达到 5TB。

优点有高性能,可扩展,操作简单,有图形化操作界面,读写性能优异等。官网

minio 部署可参考这篇:Minio 详细安装部署步骤

SpringBoot 快速整合 minio

1、添加 Maven 依赖

pom.xml 文件中添加MinIO客户端依赖项

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.2.2</version>
</dependency>
<!-- 如果 minio 版本是8.3.4以上 okhttp 一定要大于 4.8.1 版本 -->
<!--        <dependency>-->
<!--            <groupId>com.squareup.okhttp3</groupId>-->
<!--            <artifactId>okhttp</artifactId>-->
<!--            <version>4.8.2</version>-->
<!--        </dependency>-->

<!-- 还用到了 fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.78</version>
</dependency>

2、配置MinIO连接信息

application.propertiesapplication.yml 文件中配置MinIO的连接信息,包括服务器地址、端口、凭据等信息

# Minio 配置
minio.endpoint=127.0.0.1:9000 #对象存储服务的URL
minio.accessKey=admin #Access key账户 写账号也可以
minio.secretKey=admin #Secret key密码
minio.bucketName=test # 桶名称
# 过期时间
minio.expire=7200
# Minio 配置
minio:
  endpoint:  127.0.0.1:9000 #对象存储服务的URL
  accessKey: admin #Access key账户 写账号也可以
  secretKey: admin #Secret key密码
  bucketName: test # 桶名称
  expire: 7200 # 过期时间

3、创建 MinIO 客户端 Bean

在 SpringBoot 应用的配置类中创建一个 MinIO客户端的 Bean,以便在应用中使用 MinIO 服务

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

/**
 * minio 配置属性
 */
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {

    /**
     * Minio 连接地址
     */
    private String endpoint;

    /**
     * accessKey 或 账号
     */
    private String accessKey;

    /**
     * secretKey 或 密码
     */
    private String secretKey;

    /**
     * 桶名称
     */
    private String bucketName;

    /**
     * 默认是秒 地址过期时间,设置默认值7200秒
     */
    private int expire = 7200;

}

4、异常枚举类

/**
 * 异常枚举类
 */
public enum ExceptionEnums {


    FILE_NAME_NOT_NULL("0001", "文件名不能为空"),
    BUCKET_NAME_NOT_NULL("0002", "桶名称不能为空"),
    FILE_NOT_EXIST("0003", "文件不存在"),
    BUCKET_NOT_EXIST("0004", "桶不存在"),
    BUCKET_NAME_NOT_EXIST("0005", "桶不存在,需要先创建桶在创建文件夹");//枚举类如果写方法的话,此处需要写分号

    private String code;

    private String msg;

    ExceptionEnums(String ecode, String emsg) {
        this.code = ecode;
        this.msg = emsg;
    }

    public String getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public static ExceptionEnums statOf(String code) {
        for (ExceptionEnums state : values())
            if (state.getCode().equals(code))
                return state;
        return null;
    }
}

5、全局异常

import org.springframework.http.HttpStatus;

/**
 * 异常
 */
public class GeneralException extends RuntimeException {

    private Integer errorCode;

    public GeneralException() {
    }

    public GeneralException(Throwable throwable) {
        super(throwable);
    }

    public GeneralException(String msg) {
        super(msg);
        this.errorCode = HttpStatus.INTERNAL_SERVER_ERROR.value();
    }

    public GeneralException(Integer errorCode, String msg) {
        super(msg);
        this.errorCode = errorCode;
    }

    public Integer getErrorCode() {
        return this.errorCode;
    }


    public void setErrorCode(Integer errorCode) {
        this.errorCode = errorCode;
    }
}

6、minio 工具类

工具类包含创建 bucket,获取全部 bucket,获取 bucket 文件名和大小列表,文件上传,获取上传文件的完整路径,创建文件夹或目录,判断 bucket 是否存在,判断文件是否存在,文件下载,删除文件,批量删除文件方法

import com.alibaba.fastjson.JSON;
import io.minio.*;
import io.minio.errors.*;
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 lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.util.*;

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


    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioProperties minioProperties;

    /**
     * 初始化Bucket
     */
    private void createBucket(String bucketName) {
        try {
            // 判断 BucketName 是否存在
            if (bucketExists(bucketName)) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 验证bucketName是否存在
     *
     * @return boolean true:存在
     */
    public boolean bucketExists(String bucketName) {
        if (StringUtils.isEmpty(bucketName)) {
            throw new GeneralException(ExceptionEnums.BUCKET_NAME_NOT_NULL.getMsg());
        }
        boolean flag = true;
        try {
            flag = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }


    /**
     * 获取全部bucket
     * <p>
     */
    public List<String> getAllBuckets() {
        List<String> list = null;
        try {
            final List<Bucket> buckets = minioClient.listBuckets();
            list = new ArrayList<>(buckets.size());
            for (Bucket bucket : buckets) {
                list.add(bucket.name());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 根据bucketName获取信息
     *
     * @param bucketName bucket名称
     * @return
     */
    public String getBucket(String bucketName) throws Exception {
        final Optional<Bucket> first = minioClient.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
        String name = null;
        if (first.isPresent()) {
            name = first.get().name();
        }
        return name;
    }

    /**
     * 获取桶中文件名和大小列表
     *
     * @param bucketName bucket名称
     * @param recursive  查询是否递归
     * @return
     */
    public List<Object> getFileList(String bucketName, boolean recursive) {
        if (StringUtils.isEmpty(bucketName)) {
            throw new GeneralException(ExceptionEnums.BUCKET_NAME_NOT_NULL.getMsg());
        }
        List<Object> items = new ArrayList<>();
        try {
            Iterable<Result<Item>> myObjects = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix("/2022-08-03/4674a894-abaf-48cb-9ea9-40a4e8560af9/Desktop").recursive(recursive).build());
            Iterator<Result<Item>> iterator = myObjects.iterator();
            String format = "{'fileName':'%s','fileSize':'%s'}";
            for (Result<Item> myObject : myObjects) {
                System.out.println(myObject.get().objectName());
            }
            while (iterator.hasNext()) {
                Item item = iterator.next().get();
                items.add(JSON.parse(String.format(format, item.objectName(), formatFileSize(item.size()))));
//                items.add(JSON.parse(String.format(format, "/".concat("test").concat("/").concat(item.objectName()), formatFileSize(item.size()))));
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info(e.getMessage());
        }
        items.remove(0);
        return items;
    }


    /**
     * 文件上传
     *
     * @param file
     * @return
     */
    public Map<String, Object> uploadFile(String bucketName, MultipartFile[] file) {
        if (file == null || file.length == 0) {
            throw new GeneralException(ExceptionEnums.FILE_NAME_NOT_NULL.getMsg());
        }
        if (StringUtils.isEmpty(bucketName)) {
            throw new GeneralException(ExceptionEnums.BUCKET_NAME_NOT_NULL.getMsg());
        }

        List<String> orgfileNameList = new ArrayList<>(file.length);
        for (MultipartFile multipartFile : file) {
            String orgfileName = multipartFile.getOriginalFilename();
            orgfileNameList.add(orgfileName);
            try {
                //文件上传
                InputStream in = multipartFile.getInputStream();
                minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(orgfileName).stream(in, multipartFile.getSize(), -1).contentType(multipartFile.getContentType()).build());
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
                log.error(e.getMessage());
            }
        }
        Map<String, Object> data = new HashMap<>();
        data.put("bucketName", bucketName);
        data.put("fileName", orgfileNameList);
        return data;
    }

    /**
     * 获取上传文件的完整路径
     *
     * @param bucketName 桶名称
     * @param fileName   文件名
     * @param expire     地址过期时间
     * @return
     */
    public String getPresignedObjectUrl(String bucketName, String fileName, Integer expire) {
        if (StringUtils.isEmpty(bucketName)) {
            throw new GeneralException(ExceptionEnums.BUCKET_NAME_NOT_NULL.getMsg());
        }
        if (StringUtils.isEmpty(fileName)) {
            throw new GeneralException(ExceptionEnums.FILE_NAME_NOT_NULL.getMsg());
        }
        expire = Objects.isNull(expire) ? minioProperties.getExpire() : expire;
        // 验证桶是否存在在
        final boolean validationBucket = bucketExists(bucketName);
        if (!validationBucket) {
            throw new GeneralException(ExceptionEnums.BUCKET_NOT_EXIST.getMsg());
        }
        // 验证文件是否存在
        final boolean validationFileName = doFileNameExist(bucketName, fileName);
        if (!validationFileName) {
            throw new GeneralException(ExceptionEnums.FILE_NOT_EXIST.getMsg());
        }
        String url = null;
        try {
            // 获取桶和文件的完整路径
            url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(fileName).method(Method.GET).expiry(expire).build());
        } catch (MinioException e) {
            log.error("Error occurred: " + e);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return url;
    }

    /**
     * 创建文件夹或目录
     *
     * @param bucketName 存储桶
     * @param objectName 目录路径
     */
    public Map<String, String> putDirObject(String bucketName, String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        // 判断桶是否存在
        if (!bucketExists(bucketName)) {
            throw new GeneralException(ExceptionEnums.BUCKET_NAME_NOT_EXIST.getMsg());
        }
        final ObjectWriteResponse response = minioClient.putObject(
                PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(
                        new ByteArrayInputStream(new byte[]{}), 0, -1)
                        .build());
        Map<String, String> map = new HashMap<>();
        map.put("etag", response.etag());
        map.put("versionId", response.versionId());
        return map;
    }

    /**
     * 判断桶是否存在
     *
     * @param bucketName 存储桶
     * @param objectName 文件夹名称(去掉/)
     * @return true:存在
     */
    public boolean doFolderExist(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()) {
                    exist = true;
                }
            }
        } catch (Exception e) {
            exist = false;
        }
        return exist;
    }

    /**
     * 判断文件是否存在
     *
     * @param fileName 对象
     * @return true:存在
     */
    public boolean doFileNameExist(String bucketName, String fileName) {
        if (StringUtils.isEmpty(bucketName)) {
            throw new GeneralException(ExceptionEnums.BUCKET_NAME_NOT_NULL.getMsg());
        }
        if (StringUtils.isEmpty(fileName)) {
            throw new GeneralException(ExceptionEnums.FILE_NAME_NOT_NULL.getMsg());
        }
        boolean exist = true;
        try {
            minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(fileName).build());
        } catch (Exception e) {
            exist = false;
        }
        return exist;
    }

    /**
     * 文件下载
     *
     * @param response
     * @param fileName
     */
    public void downloadFile(HttpServletResponse response, String bucketName, String fileName) {
        if (StringUtils.isEmpty(bucketName)) {
            throw new GeneralException(ExceptionEnums.BUCKET_NAME_NOT_NULL.getMsg());
        }
        if (StringUtils.isEmpty(fileName)) {
            throw new GeneralException(ExceptionEnums.FILE_NAME_NOT_NULL.getMsg());
        }
        // 判断文件是否存在
        final boolean flag = doFileNameExist(bucketName, fileName);
        if (!flag) {
            throw new GeneralException(ExceptionEnums.FILE_NOT_EXIST.getMsg());
        }
        InputStream in = null;
        try {
            // 获取对象信息
            StatObjectResponse stat = minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(fileName).build());
            response.setContentType(stat.contentType());
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            //文件下载
            in = minioClient.getObject(
                    GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
            IOUtils.copy(in, response.getOutputStream());
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    log.error(e.getMessage());
                }
            }
        }
    }
    /**
     * 删除文件
     *
     * @param bucketName bucket名称
     * @param fileName   文件名称
     *                   说明:当前方法不能真正删除,需要验证
     */
    public void deleteFile(String bucketName, String fileName) {
        if (StringUtils.isEmpty(bucketName)) {
            throw new GeneralException(ExceptionEnums.BUCKET_NAME_NOT_NULL.getMsg());
        }
        if (StringUtils.isEmpty(fileName)) {
            throw new GeneralException(ExceptionEnums.FILE_NAME_NOT_NULL.getMsg());
        }
        try {
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());
        } catch (Exception e) {
            log.error(e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 批量文件删除
     *
     * @param bucketName bucket名称
     * @param fileNames  文件名
     */
    public void deleteBatchFile(String bucketName, List<String> fileNames) {
        if (StringUtils.isEmpty(bucketName)) {
            throw new GeneralException(ExceptionEnums.BUCKET_NAME_NOT_NULL.getMsg());
        }
        if (CollectionUtils.isEmpty(fileNames)) {
            throw new GeneralException(ExceptionEnums.FILE_NAME_NOT_NULL.getMsg());
        }
        try {
            List<DeleteObject> objects = new LinkedList<>();
            for (String fileName : fileNames) {
                objects.add(new DeleteObject(fileName));
            }
            Iterable<Result<DeleteError>> results =
                    minioClient.removeObjects(
                            RemoveObjectsArgs.builder().bucket(bucketName).objects(objects).build());
            for (Result<DeleteError> result : results) {
                DeleteError error = result.get();
                log.error("Error occurred: " + error);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("批量删除失败!error:{}", e);
        }
    }

    /**
     * 文件大小
     *
     * @param fileS
     * @return
     */
    private static String formatFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + " B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + " KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + " MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + " GB";
        }
        return fileSizeString;
    }
}

7、文件调用接口

上传文件,获取上传文件完整路径,文件下载,文件删除,批量删除文章来源地址https://www.toymoban.com/news/detail-859184.html

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

@RestController
public class MinioController {

    @Autowired
    private MinioUtils minioUtils;

    /**
     * 获取桶中文件名和大小列表
     *
     * @return
     */
    @GetMapping("/getFileList")
    public List<Object> getFileList() {
        return minioUtils.getFileList("test", true);
    }

    /**
     * 判断文件是否存在
     *
     * @param bucketName
     * @param fileName
     * @return
     */
    @GetMapping("/doFileNameExist")
    public boolean doFileNameExist(String bucketName, String fileName) {
        return minioUtils.doFolderExist(bucketName, fileName);
    }

    /**
     * 上传文件
     *
     * @param file
     * @return
     */
    @PostMapping("/uploadFiles")
    public Map<String, Object> uploadFiles(String bucketName, @RequestParam(name = "file", required = false) MultipartFile[] file) {
        if (file == null || file.length == 0) {
            throw new GeneralException(ExceptionEnums.FILE_NAME_NOT_NULL.getMsg());
        }
        if (StringUtils.isEmpty(bucketName)) {
            throw new GeneralException(ExceptionEnums.BUCKET_NAME_NOT_NULL.getMsg());
        }
        return minioUtils.uploadFile(bucketName, file);
    }

    /**
     * 获取上传文件的完整浏览路径
     *
     * @param filename
     * @return
     */
    @GetMapping("/getPresignedObjectUrl")
    public String getPresignedObjectUrl(@RequestParam(name = "filename") String filename) {
        return minioUtils.getPresignedObjectUrl("test", filename, null);
    }

    /**
     * 文件下载
     *
     * @param response
     * @param fileName
     */
    @GetMapping("/downloadFile")
    public void downloadFile(HttpServletResponse response, @RequestParam("fileName") String fileName) {
        minioUtils.downloadFile(response, "test", fileName);
    }

    /**
     * 删除单个文件
     *
     * @param fileName 完整路径(不包含bucket)
     */
    @DeleteMapping("/deleteFile")
    public void deleteFile(String bucketName, String fileName) {
        minioUtils.deleteFile(bucketName, fileName);
    }

    /**
     * 批量删除文件
     *
     * @param fileNames 完整路径(不包含bucket)
     */
    @DeleteMapping("/deleteBatchFile")
    public void deleteBatchFile(String bucketName, @RequestParam("fileNames") List<String> fileNames) {
        minioUtils.deleteBatchFile(bucketName, fileNames);
    }
}

到了这里,关于SpringBoot整合Minio的详细步骤的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MinIO安装配置访问以及SpringBoot整合MinIO

    详细介绍了如何在CentOS7和Windows系统上安装配置MinIO对象存储服务,并提供了SpringBoot项目与MinIO整合的步骤,帮助开发者快速实现文件的上传、下载与管理。

    2024年02月04日
    浏览(50)
  • SpringBoot3整合MinIO

    配套视频:SpringBoot3整合MinIO MinIO项目应用可参考视频 【SpringBoot3+Vue3+Uniapp小程序项目实战】 MinIO 是一个基于 Apache License v2.0 开源协议的对象存储服务。它兼容亚马逊 S3 云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器

    2024年02月21日
    浏览(55)
  • Minio安装及整合SpringBoot

    一. MinIO概述 官网地址:https://minio.org.cn MinIO是一款基于Apache License v2.0开源协议的分布式文件系统(或者叫对象存储服务),可以做为云存储的解决方案用来保存海量的图片、视频、文档等。由于采用Golang实现,服务端可以工作在Windows、Linux、 OS X和FreeBSD上。配置简单,基本

    2024年01月19日
    浏览(41)
  • SpringBoot整合Ldap--超详细方法讲解

    LDAP(轻量目录访问协议)是一种用于访问和维护分布式目录信息服务的协议。目录服务是一种存储和检索信息的服务,通常用于存储组织内的用户信息、组织结构、网络设备等数据。LDAP是一种轻量级的协议,设计用于在目录中进行查找和修改操作,而不是用于传输大量的数

    2024年02月05日
    浏览(35)
  • 【微服务】springboot整合minio详解

    目录 一、前言 二、Minio 概述 2.1 Minio简介 2.1 Minio特点 三、Minio 环境搭建

    2024年02月04日
    浏览(40)
  • SpringBoot整合Minio(实现上传与下载)

    MinIO 是一款高性能、分布式的对象存储系统 . 它是一款软件产品, 可以100%的运行在标准硬件。即X86等低成本机器也能够很好的运行MinIO。 1.导入环境所需要的依赖 2.application.yml中进行minio的配置 3.MinIoConfig.class 配置类  此类主要做一些连接Minio实例化对象的配置  4.AjaxResult.cl

    2024年02月07日
    浏览(62)
  • SpringBoot整合Minio实现文件上传、下载

    SpringBoot整合Minio实现文件上传、下载: 1,介绍高性能分布式存储文件服务Minio:Minio是 基于Go语言编写的对象存储服务 , 适合于存储大容量非结构化的数据 ,例如 图片、音频、视频、日志文件、备份数据和容器/虚拟机镜像等 ,而一个对象文件可以是任意大小,从几kb到最

    2024年02月06日
    浏览(50)
  • linux安装minio以及springboot整合使用

    1.新建文件夹 2.进入文件夹 3.下载minio,链接可从官网获取 下载下来后会在当前所在文件夹看到minio文件 4.赋予权限 要给下载下来的minio赋予权限,不然后面无法启动 赋予权限之后如图 5.开放端口 因为我后面会指定minio使用9090和9000端口,所以先开放这两个端口,如果你指定的

    2024年02月10日
    浏览(41)
  • Springboot整合minio组件-分布式文件存储

    一、快速开始 Minlo说明: Minio是Apcche旗下的一款开源的轻量级文件服务器,基于对象存储,协议是基于Apache License v2.0,开源可用于商务。 Minio主要用来存储非结构化的数据,类似文件,图片,照片,日志文件,各类备份文件等,按照官网描述,文件的大小从几KB到5TB。 Minio提

    2024年02月11日
    浏览(55)
  • SpringBoot整合minio,文件的上传下载,批量获取

    Minio是GlusterFS创始人之一Anand Babu Periasamy发布新的开源项目。基于Apache License v2.0开源协议的对象存储项目,采用Golang实现,客户端支Java,Python,Javacript, Golang语言。 其设计的主要目标是作为私有云对象存储的标准方案。主要用于存储海量的图片,视频,文档等。非常适合于存储

    2024年02月12日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包