当前位置:

首页 > 编程开发 > SpringBoot怎么使用Minio进行文件存储

SpringBoot怎么使用Minio进行文件存储

一、minioMinIO是一个高性能的对象存储原生支持Kubernetes部署的解决方案。MinIO提供了一个AmazonWebServicesS3兼容API并支持所有核心S3功能。MinIO对象存储使用buckets来组织对象。存储桶类似于文件系统中的文件夹或目录,其中每个桶可以容纳任意数量的对象。MinIO存储桶提供与AWSS3存储桶相同的功能。其中MinIO的优势有:高性能:MinIO是全球领先的对象存储先锋,在标准硬件上,读/写速度上高达183GB/秒和171GB/秒。可扩展性:MinIO利用了w

本文目录

    一、minio

    MinIO 是一个高性能的对象存储原生支持 Kubernetes 部署的解决方案。 MinIO 提供了一个 Amazon Web Services S3 兼容 API 并支持所有核心 S3 功能。

    MinIO 对象存储使用 buckets 来组织对象。 存储桶类似于文件系统中的文件夹或目录,其中每个 桶可以容纳任意数量的对象。 MinIO 存储桶提供 与 AWS S3 存储桶相同的功能。

    其中 MinIO 的优势有:

    高性能:

    MinIO是全球领先的对象存储先锋,在标准硬件上,读/写速度上高达183 GB / 秒 和 171 GB / 秒。

    可扩展性:

    MinIO利用了web缩放器的来之不易的知识,为对象存储带来了简单的存储缩放模型, 在 MinIO, 扩展从单个群集开始,该群集可以与其他MinIO群集联合以创建全局名称空间, 并在需要时可以跨越多个不同的数据中心。 通过添加更多集群可以扩展名称空间, 更多机架,直到实现目标。

    云原生支持:

    MinIO 是在过去4年的时间内从0开始打造的一款软件 ,符合一切原生云计算的架构和构建过程,并且包含最新的云计算的全新的技术和概念。 其中包括支持Kubernetes 、微服和多租户的的容器技术。使对象存储对于 Kubernetes更加友好。

    源码开放与企业级支持:

    MinIO 基于Apache V2 license 100% 开放源代码 。 这就意味着 MinIO的客户能够自动的、无限制、自由免费使用和集成MinIO、自由的创新和创造、 自由的去修改、自由的再次发行新的版本和软件. 确实, MinIO 强有力的支持和驱动了很多世界500强的企业。 此外,其部署的多样性和专业性提供了其他软件无法比拟的优势。

    在实验开始前请确保安装完成了 minio :

    SpringBoot怎么使用Minio进行文件存储

    二、SpringBoot 使用 Minio 进行文件存储

    首先新建一个 SpringBoot 项目,在 pom 中引入 minio 依赖:

    
        io.minio
        minio
        8.2.1
    

    在配置文件中,声明出 minio 的信息:

    minio:
      url: http://192.168.40.169:9000   # minio配置的地址,端口9000,注意不是控制台的端口
      accessKey: minioadmin   # 账号
      secretKey: minioadmin   # 密码
      bucketName: test-bucket  # MinIO桶名字

    下面创建一个配置类,对 MinioClient 进行创建:

    @Data
    @Configuration
    @ConfigurationProperties(prefix = "minio")
    public class MinioConfig {
        /**
         * 服务地址
         */
        private String url;
     
        /**
         * 用户名
         */
        private String accessKey;
     
        /**
         * 密码
         */
        private String secretKey;
     
        /**
         * 存储桶名称
         */
        private String bucketName;
    
        @Bean
        public MinioClient getMinioClient() throws Exception {
            MinioClient minioClient = MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();
            //判断桶是否存在,不存在则新建
            if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())){
                minioClient.makeBucket(MakeBucketArgs.builder()
                        .bucket(bucketName)
                        .build());
            }
            return minioClient;
        }
    }

    下面创建一个工具类 MinioTool 将常用的操作封装在工具类中:

    @Component
    public class MinioTool {
        
        @Autowired
        private MinioClient minioClient;
    
        @Autowired
        private MinioConfig minioConfig;
     
        /**
         * 查看存储bucket是否存在
         *
         * @param bucketName 存储bucket
         * @return boolean
         */
        public Boolean bucketExists(String bucketName) {
            Boolean found;
            try {
                found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return found;
        }
     
        /**
         * 创建存储bucket
         *
         * @param bucketName 存储bucket名称
         * @return Boolean
         */
        public Boolean makeBucket(String bucketName) {
            try {
                minioClient.makeBucket(MakeBucketArgs.builder()
                        .bucket(bucketName)
                        .build());
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
     
        /**
         * 删除存储bucket
         *
         * @param bucketName 存储bucket名称
         * @return Boolean
         */
        public Boolean removeBucket(String bucketName) {
            try {
                minioClient.removeBucket(RemoveBucketArgs.builder()
                        .bucket(bucketName)
                        .build());
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
    
        /**
         * 查看文件对象
         *
         * @param bucketName 存储bucket名称
         * @return 存储bucket内文件对象信息
         */
        public Iterable> listObjects(String bucketName) {
            Iterable> results = minioClient.listObjects(
                    ListObjectsArgs.builder().bucket(bucketName).build());
            return results;
        }
    
        /**
         * 批量删除文件对象
         *
         * @param bucketName 存储bucket名称
         * @param objects    对象名称集合
         */
        public Iterable> removeObjects(String bucketName, List objects) {
            List dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());
            Iterable> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());
            return results;
        }
    
    
        /**
         * 文件上传
         * 文件名称相同会覆盖
         * @param file       文件
         * @return Boolean
         */
        public Boolean upload(MultipartFile file, String fileName) {
            try {
                if (!bucketExists(minioConfig.getBucketName())) {
                    makeBucket(minioConfig.getBucketName());
                }
                PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(minioConfig.getBucketName()).object(fileName)
                        .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
                minioClient.putObject(objectArgs);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
     
        /**
         * 文件下载
         *
         * @param fileName   文件名称
         * @param res        response
         * @return Boolean
         */
        public void download(String fileName, HttpServletResponse res) {
            GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(minioConfig.getBucketName())
                    .object(fileName).build();
            try (GetObjectResponse response = minioClient.getObject(objectArgs)) {
                byte[] buf = new byte[1024];
                int len;
                try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {
                    while ((len = response.read(buf)) != -1) {
                        os.write(buf, 0, len);
                    }
                    os.flush();
                    byte[] bytes = os.toByteArray();
                    res.setCharacterEncoding("utf-8");
                    //设置强制下载不打开
                    res.setContentType("application/force-download");
                    res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
                    try (ServletOutputStream stream = res.getOutputStream()) {
                        stream.write(bytes);
                        stream.flush();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public String getFileUrl(String fileName){
            return StringFormatter.concat(minioConfig.getUrl(), "/", minioConfig.getBucketName(), "/", fileName).getValue();
        }
    
    }

    编写测试接口,进行测试:

    @Component
    public class MinioTool {
        
        @Autowired
        private MinioClient minioClient;
    
        @Autowired
        private MinioConfig minioConfig;
     
        /**
         * 查看存储bucket是否存在
         *
         * @param bucketName 存储bucket
         * @return boolean
         */
        public Boolean bucketExists(String bucketName) {
            Boolean found;
            try {
                found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return found;
        }
     
        /**
         * 创建存储bucket
         *
         * @param bucketName 存储bucket名称
         * @return Boolean
         */
        public Boolean makeBucket(String bucketName) {
            try {
                minioClient.makeBucket(MakeBucketArgs.builder()
                        .bucket(bucketName)
                        .build());
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
     
        /**
         * 删除存储bucket
         *
         * @param bucketName 存储bucket名称
         * @return Boolean
         */
        public Boolean removeBucket(String bucketName) {
            try {
                minioClient.removeBucket(RemoveBucketArgs.builder()
                        .bucket(bucketName)
                        .build());
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
    
        /**
         * 查看文件对象
         *
         * @param bucketName 存储bucket名称
         * @return 存储bucket内文件对象信息
         */
        public Iterable> listObjects(String bucketName) {
            Iterable> results = minioClient.listObjects(
                    ListObjectsArgs.builder().bucket(bucketName).build());
            return results;
        }
    
        /**
         * 批量删除文件对象
         *
         * @param bucketName 存储bucket名称
         * @param objects    对象名称集合
         */
        public Iterable> removeObjects(String bucketName, List objects) {
            List dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());
            Iterable> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());
            return results;
        }
    
    
        /**
         * 文件上传
         * 文件名称相同会覆盖
         * @param file       文件
         * @return Boolean
         */
        public Boolean upload(MultipartFile file, String fileName) {
            try {
                if (!bucketExists(minioConfig.getBucketName())) {
                    makeBucket(minioConfig.getBucketName());
                }
                PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(minioConfig.getBucketName()).object(fileName)
                        .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
                minioClient.putObject(objectArgs);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
     
        /**
         * 文件下载
         *
         * @param fileName   文件名称
         * @param res        response
         * @return Boolean
         */
        public void download(String fileName, HttpServletResponse res) {
            GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(minioConfig.getBucketName())
                    .object(fileName).build();
            try (GetObjectResponse response = minioClient.getObject(objectArgs)) {
                byte[] buf = new byte[1024];
                int len;
                try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {
                    while ((len = response.read(buf)) != -1) {
                        os.write(buf, 0, len);
                    }
                    os.flush();
                    byte[] bytes = os.toByteArray();
                    res.setCharacterEncoding("utf-8");
                    //设置强制下载不打开
                    res.setContentType("application/force-download");
                    res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
                    try (ServletOutputStream stream = res.getOutputStream()) {
                        stream.write(bytes);
                        stream.flush();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public String getFileUrl(String fileName){
            return StringFormatter.concat(minioConfig.getUrl(), "/", minioConfig.getBucketName(), "/", fileName).getValue();
        }
    
    }

    三、测试

    测试上传文件:

    SpringBoot怎么使用Minio进行文件存储

    如果使用 返回的 url 直接访问文件,可以发现返回权限不足:

    SpringBoot怎么使用Minio进行文件存储

    这里需要改一下 Bucket 的 Access Policy ,默认为 private,可以修改为 public 便无需认证,但安全性无法保证:

    SpringBoot怎么使用Minio进行文件存储

    SpringBoot怎么使用Minio进行文件存储

    SpringBoot怎么使用Minio进行文件存储

    再次进行访问,文件就可以打开了:

    SpringBoot怎么使用Minio进行文件存储

    如果需要保持 private ,可以通过 MinioClient 进行下载,使用 download 测试接口下载文件:http://localhost:8080/file/download/20cab4e3979eba6003f95aca0dc75c63.jpg

    SpringBoot怎么使用Minio进行文件存储

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    Windows下Minio安装与使用教程
    Windows下Minio安装与使用教程

    Windows下Minio的安装以及基本使用Minio是什么?Minio是一个开源的、云原生的分布式对象存储系统,是一个基于ApacheLicensev2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据。它一大特点就是轻量,虽然轻量,却拥有着不错的性能。使用简单,功能强大,支持各种平台,单个文件最大5TB,兼容AmazonS3接口,提供了Java、Python、GO等多版本SDK支持。官网:https://www.minio.org.cn接下来我们介

    springBoot项目常用目录有哪些
    springBoot项目常用目录有哪些

    springBoot项目常用目录springBoot项目的目录结构及名规范介绍基于SpringBoot开发时的目录结构及命名规范,通过介绍能够为你解决,在实际项目中如何规划目录结构?如何命名目录更规范?各个目录分别代表什么含义?等三个问题。目录说明servicex//项目名|-admin-ui//管理服务前端代码(一般将UI和SERVICE放到一个工程中,便于管理)|-servicex-auth//模块1|-servicex-common//模块2|-servicex-gateway//模块3|-serv

    使用PHP搭建MinIO分布式对象存储系统
    使用PHP搭建MinIO分布式对象存储系统

    随着云计算和大数据技术的发展,越来越多的企业和组织开始关注数据存储和处理的问题。传统的存储方案显然已经无法满足现代技术的需求,因此分布式对象存储成为了一个备受关注的话题。分布式对象存储的核心思想是将数据分散存储在多个节点上,通过智能的负载均衡和数据备份,实现更高效、更安全的数据管理。在开源领域中,MinIO是一个备受推崇的分布式对象存储实现方案之一,本文将介

    解析SpringBoot和SpringMVC之间的异同
    解析SpringBoot和SpringMVC之间的异同

    解析SpringBoot和SpringMVC之间的异同SpringBoot和SpringMVC是Java领域中非常重要的开发框架。虽然它们都属于Spring框架的一部分,但是在使用和功能上有一些明显的区别。本文将对SpringBoot和SpringMVC进行比较,解析它们之间的异同。首先,让我们来了解一下SpringBoot。SpringBo

    探索SpringCloud和SpringBoot在微服务领域的不同应用方式
    探索SpringCloud和SpringBoot在微服务领域的不同应用方式

    近年来,随着云计算和分布式架构的兴起,微服务架构的应用越来越广泛。而SpringCloud和SpringBoot作为Java开发中的两个重要框架,对于微服务的实现起到了重要的作用。然而,很多人对于它们在微服务领域的不同应用方式还存在一定的疑惑。本文将从不同的角度探索SpringCloud和SpringBoot在微服务中的应用方式。首先,我们来了解一下Spri

    SpringBoot和SpringMVC有何区别?
    SpringBoot和SpringMVC有何区别?

    SpringBoot与SpringMVC的不同之处在哪里?SpringBoot和SpringMVC是两个非常流行的Java开发框架,用于构建Web应用程序。尽管它们经常分别被使用,但它们之间的不同之处也是很明显的。首先,SpringBoot可以被看作是一个Spring框架的扩展或者增强版。它旨在简化Spring应用程序的初始化和配置过程,以帮助开发人

    比较SpringBoot和SpringMVC的异同
    比较SpringBoot和SpringMVC的异同

    SpringBoot和SpringMVC都是Java开发中常用的框架,但它们之间有一些明显的差异。本文将探究这两个框架的特点和用途,并对它们的差异进行比较。首先,我们来了解一下SpringBoot。SpringBoot是由Pivotal团队开发的,它旨在简化基于Spring框架的应用程序的创建和部署。它提供了一种快速、轻量级的方式来构建独立的、可执行

    SpringBoot与SpringMVC的不同点是什么?
    SpringBoot与SpringMVC的不同点是什么?

    SpringBoot和SpringMVC是Java开发中常用的两个框架,它们都是由Spring框架所提供的,但在功能和使用方式上有着一些区别。本文将分别介绍SpringBoot和SpringMVC的特点和区别。一、SpringBoot的特点:简化配置:SpringBoot通过约定优于配置的原则,大大简化了项目的配置过程。它可以自动配置项目所需要的参数,开发人

    比较和选择指南:SpringCloud与SpringBoot的功能比较
    比较和选择指南:SpringCloud与SpringBoot的功能比较

    SpringCloud和SpringBoot是目前Java领域中最热门的开源框架,它们分别提供了一套完善的微服务架构和快速构建应用程序的解决方案。本文将对它们的功能进行比较,并给出选择指南,以帮助读者了解它们的优势和适用场景。SpringBoot是一个用于开发Java应用程序的框架,它提供了一个简化的开发流程,集成了大量常用的功能和组件,减少了开发者的工作量

    SpringCloud与SpringBoot:分析它们之间的相似与不同
    SpringCloud与SpringBoot:分析它们之间的相似与不同

    深入剖析SpringCloud和SpringBoot的异同引言:在构建企业级应用程序时,Spring框架已经成为开发者们的首选。它提供了一种简单而强大的方式来构建独立于平台的应用程序。Spring框架由两个核心模块组成:SpringBoot和SpringCloud。虽然它们都可以帮助开发者快速搭建应用程序,但它们的目标和用途存在一些差异。本文将深入剖析Spr

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。