SpringBoot整合Minio(支持公有及私有bucket)

news2024/11/16 5:53:34
😊 @ 作者: 一恍过去
💖 @ 主页: https://blog.csdn.net/zhuocailing3390
🎊 @ 社区: Java技术栈交流
🎉 @ 主题: SpringBoot整合Minio(支持公有及私有bucket)
⏱️ @ 创作时间: 2024年06月19日

目录

  • 1、Bucket、Object
  • 2、常用API
  • 3、整合SpringBoot
    • 3.1、yaml配置
    • 3.2、MinIo配置
    • 3.3、Bucket 操作
    • 3.4、Object操作
      • 1. 上传文件
      • 2、获取文件状态(是否存在)
      • 3、生成带签名公共访问连接
      • 4、下载文件流
      • 5、获取文件列表
      • 6、删除文件信息

1、Bucket、Object

  • Bucket 是存储Object的逻辑空间,每个Bucket之间的数据是相互隔离的,对用户而言,相当于存放文件的顶层文件夹;

  • Object 是存储到MinIO的基本对象,对用户而言,相当于文件;

2、常用API

  • bucketExists():用于检查指定的存储桶是否存在,返回布尔值,表示存储桶是否存在;

  • makeBucket():用于创建一个新的存储桶(bucket),需要指定存储桶的名称;

  • listBuckets():用于列出用户有权访问的所有存储桶,返回存储桶的列表;

  • removeBucket():用于删除一个已存在的存储桶(bucket),删除失败会抛出异常;

  • putObject():用于上传文件到指定的存储桶;

  • statObject():用于检查指定的对象(文件)的状态,判断是否存在;

  • getPresignedObjectUrl():用于生成一个对象(文件)的签名URL,以便可以通过HTTP访问;

  • getObject():用于从指定的存储桶中下载文件;

  • listObjects():用于列出指定存储桶中的所有对象(文件);

  • removeObject():用于删除指定存储桶中的对象,需要指定存储桶名称和对象键;

3、整合SpringBoot

引入POM包:

    <dependencies>
		<!-- minio -->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.5.9</version>
        </dependency>
	</dependencies>

3.1、yaml配置

minio:
  # 连接地址
  endpoint: http://127.0.0.1:9000
  # 用户名
  accessKey: admin
  # 密码
  secretKey: 123456789
  # 设置共有桶,具体名称可以在MinIo后台设置,可以直接访问,格式:http://1ip:port/bucketName/fileName
  publicBucket: public-test
  # 设置私有桶,具体名称可以在MinIo后台设置,需要通过getPresignedObjectUrl方法获取签名链接
  privateBucket: private-test

3.2、MinIo配置

MinIOInfoConfig:

@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinIOInfoConfig {

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

    /**
     * 用户名
     */
    private String accessKey;

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

    /**
     * 私有bucket
     */
    private String privateBucket;

    /**
     * 公共bucket
     */
    private String publicBucket;

}

MinioConfig:

import io.minio.MinioClient;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MinioConfig {

    @Resource
    private MinIOInfoConfig minIOInfoConfig;

    @Bean
    public MinioClient minioClient() {
        //链式编程,构建MinioClient对象
        return MinioClient.builder()
                .endpoint(minIOInfoConfig.getEndpoint())
                .credentials(minIOInfoConfig.getAccessKey(), minIOInfoConfig.getSecretKey())
                .build();
    }
}

3.3、Bucket 操作

上传文件前,需要先进行Bucket 的创建操作,可以直接到MinIo后台进行创建,也可以通过API接口进行创建,代码示例如下

@Service
public class MinIOService {
    
    @Resource
    private MinioClient minioClient;

    public void bucket() {
        try {
            String bucketName = "test-bucket";

            // 判断是否存在
            boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            System.out.println("bucketExists1 = " + bucketExists);

            // 创建
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());

            // 再次判断
            bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            System.out.println("bucketExists2 = " + bucketExists);

            // 查询列表
            List<Bucket> bucketList = minioClient.listBuckets();
            List<String> list = bucketList.stream().map(Bucket::name).toList();
            System.out.println("bucketList = " + list);

            // 删除
            minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());

            // 再次判断
            bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            System.out.println("bucketExists3 = " + bucketExists);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

3.4、Object操作

1. 上传文件

@Service
public class MinIOService {
    
    @Resource
    private MinioClient minioClient;
    
    @Resource
    private MinIOInfoConfig minIOInfoConfig;
    
        public void upload(MultipartFile file) {
        try {
            String originalFilename = file.getOriginalFilename();
            
            // 上传文件
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(minIOInfoConfig.getPrivateBucket())
                    .object(originalFilename)
                    .stream(file.getInputStream(), file.getSize(), -1)
                    .build()
            );
            // 判断文件是否存在
            
            // 获取访问地址
            
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

2、获取文件状态(是否存在)

@Service
public class MinIOService {
    
    @Resource
    private MinioClient minioClient;
    
    @Resource
    private MinIOInfoConfig minIOInfoConfig;
    
    public void fileState(String fileName) {
        try {
            StatObjectResponse response = minioClient.statObject(StatObjectArgs.builder()
                    .bucket(minIOInfoConfig.getPrivateBucket())
                    .object(fileName)
                    .build());
            System.out.println("response = " + response);
        } catch (Exception e) {
            log.error("文件不存在");
        }
    }
}

3、生成带签名公共访问连接

1、通过getPresignedObjectUrl方法,生成一个带到期时间、签名的URL,这个地址可以提供给没有登录的第三方共享访问或者上传对象,针对于Bucket为私有的情况。

2、对于共有的的文件,可以通过http://1ip:port/bucketName/fileName格式直接访问。

@Service
public class MinIOService {
    
    @Resource
    private MinioClient minioClient;
    
    @Resource
    private MinIOInfoConfig minIOInfoConfig;
    
    public String getPresignedObjectUrl(String fileName) {
        try {
            String presignedObjectUrl = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .bucket(minIOInfoConfig.getPrivateBucket())
                    .object(fileName)
                    // 设置过期时间,3分钟
                    .expiry(3, TimeUnit.MINUTES)
                    .method(Method.GET)
                    .build());
            System.out.println(presignedObjectUrl);

            return presignedObjectUrl;
        } catch (Exception e) {
            return "获取链接失败";
        }
    }
}

4、下载文件流

1、通过getObject()方法可以直接获取文件流,将文件流通过浏览器直接下;

2、使用该方式的好处是,在业务上可以由前端传入文件Id,服务端通过文件Id查询到文件名称再调用MinIO的API接口获取文件流,这样可以实现系统自身对文件的水平权限管理。

@Service
public class MinIOService {
    
    @Resource
    private MinioClient minioClient;
    
    @Resource
    private MinIOInfoConfig minIOInfoConfig;
    
    public void getObjectByStream(String fileName, HttpServletResponse response) {
        try {
            GetObjectResponse getObjectResponse = minioClient.getObject(GetObjectArgs.builder()
                    .bucket(minIOInfoConfig.getPrivateBucket())
                    .object(fileName)
                    .build());

            // 转化为流
            getObjectResponse.transferTo(response.getOutputStream());
        } catch (Exception e) {
            log.error("获取文件失败");
        }
    }
}

5、获取文件列表

@Service
public class MinIOService {
    
    @Resource
    private MinioClient minioClient;
    
    @Resource
    private MinIOInfoConfig minIOInfoConfig;
    
    public void listObjects() {
        try {
            Iterable<Result<Item>> listObjects = minioClient.listObjects(ListObjectsArgs.builder()
                    .bucket(minIOInfoConfig.getPrivateBucket())
                    // 以xx开头的文件名称
                    // .prefix("/")
                    .build());

            listObjects.forEach(itemResult -> {
                try {
                    Item item = itemResult.get();
                    log.info("文件名称:" + item.objectName());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
        } catch (Exception e) {
            log.error("获取文件失败");
        }
    }
}

6、删除文件信息

@Service
public class MinIOService {
    
    @Resource
    private MinioClient minioClient;
    
    @Resource
    private MinIOInfoConfig minIOInfoConfig;
    
    public void removeObject(String fileName) {
        try {
            // 单个删除
            minioClient.removeObject(RemoveObjectArgs.builder()
                    .bucket(minIOInfoConfig.getPrivateBucket())
                    .object(fileName)
                    .build());

            // 批量删除
            List<DeleteObject> list = new ArrayList<>();
            list.add(new DeleteObject(fileName));
            minioClient.removeObjects(RemoveObjectsArgs.builder()
                    .bucket(minIOInfoConfig.getPrivateBucket())
                    .objects(list)
                    .build());
        } catch (Exception e) {
            log.error("删除文件失败");
        }
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1839667.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习课程复习——决策树

Q:这三个算法哪一个可以用来做回归? CART Q:这学期学过的分类算法有哪些? 支持向量机、决策树、k近邻、逻辑回归、朴素贝叶斯、ANN (注意区分分类算法与聚类算法) Q:计算题 根据以上条件,生成相应的决策树 1. ID3算法

Jenkins教程-5-gitee自动化测试任务构建

上一小节我们学习了Jenkins构建gitlab自动化测试任务的方法&#xff0c;本小节我们讲解一下gitee自动化测试任务的构建方法。 接下来我们以windows系统为例&#xff0c;讲解一下构建实际自动化测试任务的具体步骤。 安装git和gitee插件 点击进入Jenkins插件管理页面 安装完插…

mac禁用电池睡眠-mac盒盖连接显示器

mac禁用电池睡眠-mac盒盖连接显示器-mac断点盒盖连接显示器 讲解&#xff1a;mac盒盖的时候连接显示器会睡眠并断开和显示器的连接&#xff0c;只有在电池->选项->选择使用电源适配器的时候防止睡眠&#xff0c;才可以连接电源线外界显示器 但是苹果的电池相当于手机电…

Linux使用lrzsz实现虚拟机和本机进行文件传输

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、lrzsz是什么&#xff1f;二、使用步骤1.下载lrzsz2.文件传输 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 使用lrzsz代替xfpt进行…

大模型时代的具身智能系列专题(一)

通用具身机器人 具身智能定义 从图灵定义看&#xff0c;知识由感知、智能体环境交互获得&#xff0c;具身智能要拥有足够的知识完成机器人任务。从字面上理解就是具有身体的智能&#xff0c;可以从交互中学习并有可能涌现新能力。近期的具身智能更多和大模型和端到端有关&…

KVB投资安全小知识:你知道情绪面、技术面与基本面的关系吗?

摘要&#xff1a;当涉及到金融市场分析时&#xff0c;情绪面、技术面和基本面是三个重要的方面。它们相互交织&#xff0c;共同影响着市场的走势和投资者的决策。下面我来详细解释它们之间的关系。 情绪面的影响 情绪面指的是投资者情绪和市场情绪&#xff0c;它反映了市场参与…

曾从钦:共同做大露酒产业蛋糕,共建露酒产业命运共同体

执笔 | 尼 奥 编辑 | 扬 灵 6月15日&#xff0c;由中国酒业协会主办、五粮液股份公司承办的以“文化焕新&#xff0c;价值绽放”为主题的第三届中国露酒T5峰会在四川省宜宾市召开&#xff0c;参会企业对当前露酒产业现状、结构性矛盾、品类价值表达等议题进行深入探讨和交…

ARM功耗管理框架之LPI

安全之安全(security)博客目录导读 思考&#xff1a;功耗管理框架&#xff1f;SCP&#xff1f;PPU&#xff1f;LPI&#xff1f;之间的关系&#xff1f;如何配合&#xff1f; 目录 一、功耗管理框架中的LPI 二、LPI分类 三、Q-Channel和P-Channel对比 四、Q-Channel和P-Ch…

QT/基于TCP的服务端实现

代码 widget.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget),p(new QTcpServer(this))//给服务器指针申请空间 {ui->setupUi(this); }Widget::~Widget() {delete ui; }void W…

VM安装Ubuntu

系统安装 先安装好VM软件&#xff08;版本> 17&#xff09; 创建新的虚拟机 步骤1&#xff1a; 步骤2&#xff1a;&#xff08;选择好对应的ISO&#xff0c;可以去官网下载&#xff09; 注意&#xff1a;ISO文件要放到 英文目录&#xff08;路径中不能有中文和空格&#…

Qt打包成单独一个.exe文件运行

程序发布 1、首先找到你所运行的Qt编译器 2、然后去项目位置找到对应的release目录下的exe文件 3、将这个exe文件复制到一个单独的文件夹下&#xff0c;这里我放在E盘的demo下面 4、右键选择在终端打开PowerShell进入步骤1新建的demo目录内 5、windeployqt 项目名.exe windepl…

【FreeRTOS】估算栈的大小

参考《FreeRTOS入门与工程实践(基于DshanMCU-103).pdf》 目录 估算栈的大小回顾简介计算说明估计函数用到的栈有多大合计 估算栈的大小 回顾 上一篇文章链接&#xff1a;http://t.csdnimg.cn/Cc8b4 传送门: 上一篇文章 上一篇文章创建的三个任务 /* 创建任务&#xff1a;声 *…

图像处理之几何变换

一、柱形畸变 import cv2 import numpy as npdef cylindrical_projection(image, f):h, w = image.shape[:2]map_x, map_y = np.meshgrid(np.arange(w), np.arange(h))x_c = w / 2y_c = h / 2theta = (map_x - x_c) / fh_c = (map_y - y_c) / np.sqrt((map_x - x_c)**2 + f**2…

音视频入门基础:H.264专题(3)——EBSP, RBSP和SODB

音视频入门基础&#xff1a;H.264专题系列文章&#xff1a; 音视频入门基础&#xff1a;H.264专题&#xff08;1&#xff09;——H.264官方文档下载 音视频入门基础&#xff1a;H.264专题&#xff08;2&#xff09;——使用FFmpeg命令生成H.264裸流文件 音视频入门基础&…

亚特全球链锯文化推广大使活动盛大启航

&#xff08;本台记者报&#xff09;链锯&#xff0c;这一象征着力量与技艺的工具&#xff0c;自诞生以来便见证了人类工业文明的进步。从最初的简易链锯到如今的多功能锂电链锯&#xff0c;彰显了人类对于技艺与科技的追求&#xff0c;其演变历程不仅映射出人类科技的巨大飞跃…

CSS3基本语法

文章目录 一、CSS引入方式二、选择器1、标签选择器2、类选择器3、id选择器4、通配符选择器 三、字体操作1、字体大小2、字体粗细3、字体样式&#xff08;是否倾斜&#xff09;4、字体修改常见字体系列 修改字体系列语法 四、文本操作1、文本缩进2、文本水平对齐方式3、文本修饰…

HarmonyOS Next 系列之从手机选择图片或拍照上传功能实现(五)

系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现&#xff08;一&#xff09; HarmonyOS Next 系列之验证码输入组件实现&#xff08;二&#xff09; HarmonyOS Next 系列之底部标签栏TabBar实现&#xff08;三&#xff09; HarmonyOS Next 系列之HTTP请求封装和Token…

CobaltStrike后渗透进阶篇

0x01 网络钓鱼攻击 钓鱼攻击简介 钓鱼攻击主要通过生成的木马诱使受害者运行后上线&#xff0c;其中木马一般都伪装成正常的程序。与此同时配合钓鱼网站可帮助攻击者模拟真实网站诱骗受害者访问&#xff0c;达到获取账号密码、上线木马等目的。接下来主要介绍后门程序的生成及…

vue-json-viewer组件 copyable失效,页面并不现实copy按钮

<json-viewer :value"props.row.param_detail.query" :expand-depth"10" copyable> </json-viewer> 官方文档中&#xff0c;说明&#xff0c;只要在json-viewer中加入 copyable属性&#xff0c;即可实现copy功能&#xff0c;如下图&#xff1…