SpringBoot集成MinIO8.0
一、安装MinIO
中文官网地址:https://www.minio.org.cn/download.shtml
官网地址:https://min.io/download
官网有相应的安装命令,可查看
建议引用相应版本的依赖
二、集成SpringBoot
1.引入依赖
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.4.3</version>
</dependency>
2.配置文件
# minio配置minio:endpoint: http://124.223.18.203:9000region:access-key: F5PKaRjxGXlbiFmarzF7secret-key: cKL8dQpLoORJ21Gw7882lUIAbA66RGKaKfsl0om2bucket: file
3.配置类
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*** 读取项目文件配置** @author qiangesoft*/
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {/*** 服务地址*/private String endpoint = "http://127.0.0.1/9000/";/*** 地区*/private String region;/*** 认证账户*/private String accessKey;/*** 认证密码*/private String secretKey;/*** 桶*/private String bucket;}
4.实例化客户端
import com.qiangesoft.rdp.starter.minio.core.MinioTemplate;
import com.qiangesoft.rdp.starter.minio.core.MinioTemplateImpl;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ObjectUtils;/*** minio自动配置** @author qiangesoft* @date 2023-09-15*/
@Slf4j
@Configuration
@ConditionalOnClass(value = {MinioClient.class})
@RequiredArgsConstructor
@EnableConfigurationProperties(MinioProperties.class)
public class MinioConfiguration {private final MinioProperties minioProperties;@Bean@ConditionalOnMissingBeanpublic MinioClient minioClient() {log.info("MinioClient initializing, url is {}, accessKey is {}!", minioProperties.getEndpoint(), minioProperties.getAccessKey());MinioClient.Builder builder = MinioClient.builder().endpoint(minioProperties.getEndpoint()).credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey());String region = minioProperties.getRegion();if (region != null && region.length() > 0) {builder.region(region);}MinioClient minioClient = builder.build();String bucket = minioProperties.getBucket();if (ObjectUtils.isEmpty(bucket)) {log.error("Bucket not empty");throw new RuntimeException("Bucket not empty");}// 初始化桶if (!this.checkExists(minioClient, bucket)) {this.createBucket(minioClient, bucket);}log.info("MinioClient initialization success!");return minioClient;}@Bean@ConditionalOnMissingBeanpublic MinioTemplate minioTemplate() {return new MinioTemplateImpl(minioProperties, minioClient());}/*** 检查桶是否存在** @param minioClient* @param bucketName* @return*/private boolean checkExists(MinioClient minioClient, String bucketName) {try {return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());} catch (Exception e) {log.error("Check bucket exists failed with error");throw new RuntimeException("Check bucket exists failed with error");}}/*** 创建桶** @param minioClient* @param bucketName*/private void createBucket(MinioClient minioClient, String bucketName) {try {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {log.error("Create bucket failed with error");throw new RuntimeException("Create bucket failed with error");}}
}
5.API使用
import io.minio.StatObjectResponse;
import io.minio.messages.Bucket;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.List;/*** minio文件服务** @author qiangesoft* @date 2023-04-21*/
public interface MinioTemplate {/*** 创建桶** @param bucketName* @throws Exception*/void createBucket(String bucketName) throws Exception;/*** 获取桶** @return*/List<Bucket> listBuckets() throws Exception;/*** 获取桶** @param bucketName* @return* @throws Exception*/Bucket getBucket(String bucketName) throws Exception;/*** 删除桶** @param bucketName* @throws Exception*/void removeBucket(String bucketName) throws Exception;/*** 上传文件** @param bucketName* @param inputStream* @param objectName* @return* @throws Exception*/String putObject(String bucketName, InputStream inputStream, String objectName) throws Exception;/*** 上传文件** @param bucketName* @param file* @return* @throws Exception*/String putObject(String bucketName, MultipartFile file) throws Exception;/*** 分享文件地址** @param bucketName* @param objectName* @param expires* @return* @throws Exception*/String getObjectURL(String bucketName, String objectName, Integer expires) throws Exception;/*** 获取文件** @param bucketName* @param objectName* @return* @throws Exception*/InputStream getObject(String bucketName, String objectName) throws Exception;/*** 获取文件** @param bucketName* @param objectName* @return* @throws Exception*/StatObjectResponse getObjectInfo(String bucketName, String objectName) throws Exception;/*** 下载文件** @param bucketName* @param filename* @param response* @throws Exception*/void download(String bucketName, String filename, HttpServletResponse response) throws Exception;/*** 删除文件** @param bucketName* @param objectName* @throws Exception*/void removeObject(String bucketName, String objectName) throws Exception;/*** 删除文件** @param bucketName* @param objectNames* @throws Exception*/void removeObjects(String bucketName, List<String> objectNames) throws Exception;
}
import com.qiangesoft.rdp.starter.minio.config.MinioProperties;
import io.minio.*;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;/*** minio文件服务实现类** @author qiangesoft* @date 2023-04-21*/
@Slf4j
public class MinioTemplateImpl implements MinioTemplate {private static final String SLASH = "/";private MinioProperties minioProperties;private MinioClient minioClient;public MinioTemplateImpl(MinioProperties minioProperties, MinioClient minioClient) {this.minioProperties = minioProperties;this.minioClient = minioClient;}@Overridepublic void createBucket(String bucketName) throws Exception {BucketExistsArgs args = BucketExistsArgs.builder().bucket(bucketName).build();boolean exists = minioClient.bucketExists(args);if (!exists) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());}}@Overridepublic List<Bucket> listBuckets() throws Exception {return minioClient.listBuckets();}@Overridepublic Bucket getBucket(String bucketName) throws Exception {Optional<Bucket> first = this.listBuckets().stream().filter(e -> e.name().equals(bucketName)).findFirst();return first.orElse(null);}@Overridepublic void removeBucket(String bucketName) throws Exception {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());}@Overridepublic String putObject(String bucketName, InputStream inputStream, String objectName) throws Exception {// 参数校验Assert.notNull(bucketName, "bucketName is not blank");Assert.notNull(inputStream, "inputStream is not null");Assert.notNull(objectName, "objectName is not blank");// 判断存储桶是否存在,不存在则创建this.createBucket(bucketName);// 上传minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(inputStream, inputStream.available(), -1).contentType("application/octet-stream").build());return bucketName + SLASH + objectName;}@Overridepublic String putObject(String bucketName, MultipartFile file) throws Exception {// 参数校验Assert.notNull(bucketName, "bucketName is not blank");Assert.notNull(file, "file is not null");// 判断存储桶是否存在 不存在则创建createBucket(bucketName);// 文件名String objectName = file.getOriginalFilename();// 上传minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build());return bucketName + SLASH + objectName;}@Overridepublic String getObjectURL(String bucketName, String objectName, Integer expires) throws Exception {return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).expiry(expires).build());}@Overridepublic InputStream getObject(String bucketName, String objectName) throws Exception {return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());}@Overridepublic StatObjectResponse getObjectInfo(String bucketName, String objectName) throws Exception {return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());}@Overridepublic void download(String bucketName, String filename, HttpServletResponse response) throws Exception {GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName).object(filename).build();GetObjectResponse objectResponse = minioClient.getObject(objectArgs);byte[] buf = new byte[1024];int len;try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {while ((len = objectResponse.read(buf)) != -1) {os.write(buf, 0, len);}os.flush();byte[] bytes = os.toByteArray();response.setCharacterEncoding("utf-8");response.setContentType("application/force-download");response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");response.addHeader("Content-Disposition", "attachment;fileName=" + filename);try (ServletOutputStream stream = response.getOutputStream()) {stream.write(bytes);stream.flush();}}}@Overridepublic void removeObject(String bucketName, String objectName) throws Exception {minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());}@Overridepublic void removeObjects(String bucketName, List<String> objectNames) throws Exception {List<DeleteObject> deleteObjectList = new ArrayList<>();for (String objectName : objectNames) {DeleteObject deleteObject = new DeleteObject(objectName);deleteObjectList.add(deleteObject);}Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(deleteObjectList).build());for (Result<DeleteError> result : results) {DeleteError error = result.get();log.error("Error in deleting object " + error.objectName() + "; " + error.message());}}
}
另有启动器版本
点击跳转
相关文章:

SpringBoot集成MinIO8.0
一、安装MinIO 中文官网地址:https://www.minio.org.cn/download.shtml 官网地址:https://min.io/download 官网有相应的安装命令,可查看 建议引用相应版本的依赖 二、集成SpringBoot 1.引入依赖 <dependency><groupId>io.…...
蓝桥等考Python组别五级007
第一部分:选择题 1、Python L5 (15分) 表达式“not a > 0”等价于下面哪个表达式?( ) a < 0a == 0a <= 0a in 0正确答案:C 2、Python L5 (15分) 执行下面的程序,当用键盘输入10时,输出结果是( )。 n &...
【装机】通过快捷键设置BIOS从U盘启动
当要重装系统的时候,是否会遇到一个问题,进入bios的时候就开始凌乱了,因为不懂得怎么用bios设置u盘启动.不要着急,下面来一波小白装机教程 总的来讲,设置电脑从U盘启动一共有两种方法: 第一种:开机时候按快捷键,然后选择U盘启动第…...

关于操作系统与内核科普
关于操作系统与内核科普 一.什么是操作系统 操作系统是管理计算机硬件与软件资源的计算机程序。它为计算机硬件和软件提供了一种中间层。 操作系统是一种软件,主要目的有三种: 一.管理计算机资源,这些资源包括CPU,内存࿰…...
算法练习3——删除有序数组中的重复项
LeetCode 26 删除有序数组中的重复项 给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums …...

《YOLOv5:从入门到实战》报错解决 专栏答疑
前言:Hello大家好,我是小哥谈。《YOLOv5:从入门到实战》专栏上线后,部分同学在学习过程中提出了一些问题,笔者相信这些问题其他同学也有可能遇到。为了让大家可以更好地学习本专栏内容,笔者特意推出了该篇专…...
[2023.09.25]:Rust编写基于web_sys的编辑器:输入光标再次定位的小结
前些天,写了探索Rust编写基于web_sys的WebAssembly编辑器:挑战输入光标定位的实践,经过后续的开发检验,我发现了一个问题,就是光标消失了。为了继续输入,用户需要再次使用鼠标点击。现在我已经弄清楚了导致…...

估计、偏差和方差
一、介绍 统计领域为我们提供了很多工具来实现机器学习目标,不仅可以解决训练集上的任务,还可以泛化。基本的概念,例如参数估计、偏差和方差,对于正式地刻画泛化、欠拟合和过拟合都非常有帮助。 二、参数估计 参数估计 是统计学…...

正态分布的概率密度函数|正态分布检验|Q-Q图
正态分布的概率密度函数(Probability Density Function,简称PDF)的函数取值是指在给定的正态分布参数(均值 μ 和标准差 σ)下,对于特定的随机变量取值 x,计算得到的概率密度值 f(x)。这个值表示…...

【接口测试】HTTP协议
一、HTTP 协议基础 HTTP 简介 HTTP 是一个客户端终端(用户)和服务器端(网站)请求和应答的标准(TCP)。通常是由客户端发起一个请求,创建一个到服务器的 TCP 连接,当服务器监听到客户…...

【重新定义matlab强大系列十四】基于问题求解有/无约束非线性优化
🔗 运行环境:Matlab 🚩 撰写作者:左手の明天 🥇 精选专栏:《python》 🔥 推荐专栏:《算法研究》 #### 防伪水印——左手の明天 #### 💗 大家好🤗ᾑ…...

MySQL 索引介绍和最佳实践
目录 一、前言二、索引类型1.1 主键索引(PRIMARY KEY)1.2 唯一索引(UNIQUE)1.3 普通索引(NORMAL)1.3.1 单列普通索引1.3.2 单列前缀普通索引1.3.3 多列普通索引1.3.4 多列前缀普通索引 1.4 空间索引&#x…...
区块链(7):p2p去中心化之初始化websoket服务端
1 整个流程梳理 服务开启onStart()连接打开onOpen()处理接收到的消息onMesage()连接关闭onClose()异常处理onError()2 创建p2p实现类 package com.example.demo.service;import com.example.demo.entity.BlockChain; import org.java_websocket.WebSocket; import org.java_we…...

原型、原型链、判断数据类型
目录 作用 原型链 引用类型:__proto__(隐式原型)属性,属性值是对象函数:prototype(原型)属性,属性值是对象 Function:本身也是函数 相关方法 person.prototype.isPrototypeOf(stu) Object.getPrototypeOf(objec…...

pycharm中配置torch
在控制台cmd中安装好torch后,在pycharm中使用torch,需要进行简单设置即可。 在pycharm中新建一个工程,在file文件中打开setting 在setting中找到project interpreter编译器 找到conda environment的环境配置,设置好相应的目录 新…...

什么是Times New Roman 字体
如何评价 Times New Roman 字体?:https://www.zhihu.com/question/24614549?sortcreated 新罗马字体是Times New Roman字体,是Office Word默认自带的英文字体之一。 中英文字体 写作中,英文和数字的标准字体为 Times New Roma…...

企业会议新闻稿怎么写?会议类新闻稿如何撰写?
企业会议新闻稿是企业对外传递信息的重要途径之一,它能够将企业的决策、动态以及成果展示给公众。本文伯乐网络传媒将详细解析企业会议新闻稿的写作要点和技巧,以及常见问题及解决方法,帮助大家更好地完成企业会议新闻稿的撰写工作。 一、企业…...
算法 滑动窗口最大值-(双指针+队列)
牛客网: BM45 题目: 数组num, 窗口大小size, 所有窗口内的最大值 思路: 用队列作为窗口,窗口内存储数组坐标,left window[0], right从数组0开始遍历完数组,每次新增元素时,(1)先对窗口大小进行收缩到size大小范围,即…...

Java 并发编程面试题——BlockingQueue
目录 1.什么是阻塞队列 (BlockingQueue)?2.BlockingQueue 有哪些核心方法?3.BlockingQueue 有哪些常用的实现类?3.1.ArrayBlockingQueue3.2.DelayQueue3.3.LinkedBlockingQueue3.4.PriorityBlockingQueue3.5.SynchronousQueue 4.✨BlockingQu…...
Ubuntu Nacos开机自启动服务
1、创建service文件 在/lib/systemd/system目录下创建nacos.service文件 [Unit] Descriptionalibaba nacos Afternetwork.target Documentationhttps://nacos.io/zh-cn/[Service] Userroot Grouproot Typeforking Environment"JAVA_HOME/usr/local/programs/jdk-8u333-li…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...

ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...

相关类相关的可视化图像总结
目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系,可直观判断线性相关、非线性相关或无相关关系,点的分布密…...