当前位置: 首页 > news >正文

SpringBoot 整合 Minio

官网:
MinIO 是一个基于 Go 实现的高性能、兼容 S3 协议的对象存储。它采用 GNU AGPL v3 开源协议,项目地址是 https://github.com/minio/minio 。

它适合存储海量的非结构化的数据,例如说图片、音频、视频等常见文件,备份数据、容器、虚拟机镜像等等,小到 1 KB,大到 5 TB 都可以支持。

添加依赖

<properties><java.version>1.8</java.version><minio.version>8.4.3</minio.version>
</properties><dependencies><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>${minio.version}</version></dependency>
</dependencies>

Minio 配置类

import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MinioConfig {@Value("${minio.url}")private String url;@Value("${minio.access-key}")private String accessKey;@Value("${minio.secret-key}")private String secretKey;@Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();}
}

application.yml 配置文件

minio:url: http://127.0.0.1:9000accessKey: 45wsHpkAIWfhghSs11XsecretKey: D9fghfg6sahgufghfgdOYrwqHqocfgh2njhfgh

MinioTemplate.java 封装方法

封装常用的上传(多文件上传、单文件上传)、获取链接、删除、下载方法,方便使用。

import com.ufan.mall.model.FileVo;
import io.minio.*;
import io.minio.http.Method;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;/*** @ClassName:MinioTemplate.java* @Description:MinioTemplate* @Author:tanyp* @Date:2023/07/27 15:49**/
@Slf4j
@Component
public class MinioTemplate {@Autowiredprivate MinioClient client;/*** @MonthName:upload* @Description: 上传文件* @Author:tanyp* @Date:2023/07/27 15:52* @Param: [file, bucketName]* @return:void**/public FileVo upload(MultipartFile file, String bucketName) {try {createBucket(bucketName);String oldName = file.getOriginalFilename();String fileName = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + UuidUtil.getRandomPwd(15) + oldName.substring(oldName.lastIndexOf("."));client.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(file.getInputStream(), file.getSize(), 0).contentType(file.getContentType()).build());String url = this.getObjUrl(bucketName, fileName);return FileVo.builder().oldFileName(oldName).newFileName(fileName).fileUrl(url.substring(0, url.indexOf("?"))).build();} catch (Exception e) {log.error("上传文件出错:{}", e);return null;}}/*** @MonthName:uploads* @Description: 上传多个文件* @Author:tanyp* @Date:2023/07/27 15:52* @Param: [file, bucketName]* @return:void**/public List<FileVo> uploads(List<MultipartFile> files, String bucketName) {try {List<FileVo> list = new ArrayList<>();createBucket(bucketName);for (MultipartFile file : files) {String oldName = file.getOriginalFilename();String fileName = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + UuidUtil.getRandomPwd(15) + oldName.substring(oldName.lastIndexOf("."));client.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(file.getInputStream(), file.getSize(), 0).contentType(file.getContentType()).build());String url = this.getObjUrl(bucketName, fileName);list.add(FileVo.builder().oldFileName(oldName).newFileName(fileName).fileUrl(url.substring(0, url.indexOf("?"))).build());}return list;} catch (Exception e) {log.error("上传文件出错:{}", e);return null;}}/*** @MonthName:download* @Description: 下载文件* @Author:tanyp* @Date:2023/07/27 15:54* @Param: [bucketName, fileName]* @return:void**/public void download(String bucketName, String fileName) throws Exception {client.downloadObject(DownloadObjectArgs.builder().bucket(bucketName).filename(fileName).build());}/*** @MonthName:getObjUrl* @Description: 获取文件链接* @Author:tanyp* @Date:2023/07/27 15:55* @Param: [bucketName, fileName]* @return:java.lang.String**/public String getObjUrl(String bucketName, String fileName) throws Exception {return client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(fileName).method(Method.GET).expiry(30, TimeUnit.SECONDS).build());}/*** @MonthName:delete* @Description: 删除文件* @Author:tanyp* @Date:2023/5/26 15:56* @Param: [bucketName, fileName]* @return:void**/public void delete(String bucketName, String fileName) throws Exception {client.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());}@SneakyThrowspublic void createBucket(String bucketName) {if (!client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {client.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());String sb = "{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": [\"*\"]},\"Action\": [\"s3:GetBucketLocation\"],\"Resource\": [\"arn:aws:s3:::" + bucketName + "\"]},{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": [\"*\"]},\"Action\": [\"s3:ListBucket\"],\"Resource\": [\"arn:aws:s3:::" + bucketName + "\"],\"Condition\": {\"StringEquals\": {\"s3:prefix\": [\"*\"]}}},{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": [\"*\"]},\"Action\": [\"s3:GetObject\"],\"Resource\": [\"arn:aws:s3:::" + bucketName + "/**\"]}]}";client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucketName).config(sb).build());}}}

FileVo.java 实体类

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class FileVo {/*** 原文件名*/private String oldFileName;/*** 新文件名*/private String newFileName;/*** 文件路径*/private String fileUrl;}

动态创建 Bucket

如何设置桶的权限?

在MinIO中,可以通过设置桶策略来控制桶的访问权限。桶策略是一个JSON格式的文本文件,用于指定哪些实体(用户、组或IP地址)可以执行哪些操作(读、写、列举等)。

MinIO桶策略的基本结构如下所示:

{"Version": "2012-10-17","Statement": [{"Action": ["action1", "action2", ...],"Effect": "Allow|Deny","Principal": {"AWS": ["arn:aws:iam::account-id:user/user-name"]},"Resource": ["arn:aws:s3:::bucket-name/object-prefix", ...]},...]
}

相关文章:

SpringBoot 整合 Minio

官网&#xff1a; MinIO 是一个基于 Go 实现的高性能、兼容 S3 协议的对象存储。它采用 GNU AGPL v3 开源协议&#xff0c;项目地址是 https://github.com/minio/minio 。 它适合存储海量的非结构化的数据&#xff0c;例如说图片、音频、视频等常见文件&#xff0c;备份数据、…...

《吐血整理》高级系列教程-吃透Fiddler抓包教程(24)-Fiddler如何优雅地在正式和测试环境之间来回切换-中篇

1.简介 在开发或者测试的过程中&#xff0c;由于项目环境比较多&#xff0c;往往需要来来回回地反复切换&#xff0c;那么如何优雅地切换呢&#xff1f;宏哥今天介绍几种方法供小伙伴或者童鞋们进行参考。 2.实际工作场景 2.1问题场景 &#xff08;1&#xff09;已发布线上…...

探索 GPTCache|GPT-4 将开启多模态 AI 时代,GPTCache + Milvus 带来省钱秘籍

世界正处于数字化的浪潮中&#xff0c;为了更好理解和分析大量数据&#xff0c;人们对于人工智能&#xff08;AI&#xff09;解决方案的需求呈爆炸式增长。 此前&#xff0c;OpenAI 推出基于 GPT-3.5 模型的智能对话机器人 ChatGPT&#xff0c;在自然语言处理&#xff08;NLP&a…...

纯css实现登录表单动效

效果图&#xff1a; 代码展示 // 我这边用的是elementUI表单校验&#xff0c;更改的样式。 <el-form:model"form":rules"rules"ref"fromList":hide-required-asterisk"true"><el-form-item prop"account"><…...

【css】外边距margin

外边距中有一个属性值比较有意思&#xff1a;inherit 值&#xff0c;继承父类的属性。 <!DOCTYPE html> <html> <head> <style> div {border: 1px solid red;margin-left: 100px; }p.ex1 {margin-left: inherit; } </style> </head> <…...

Cpp8 — 二叉搜索树

二叉搜索树&#xff08;搜索二叉树、二叉排序树&#xff09; 二叉搜索树又称二叉排序树&#xff0c;它要么是一棵空树&#xff0c;要么是具有以下性质的二叉树&#xff1a; 1.若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 2.若它的右子树不为空&…...

【实操教程】如何开始用Qt Widgets编程?(一)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 在本文中&#xff0…...

openmp和avx配置

实际场景&#xff1a; 项目中数据拷贝慢&#xff08;使用的是memcpy&#xff09;&#xff0c;希望能加速拷贝&#xff0c;所以尝试了使用avx的流方式&#xff0c;和openmp方式处理 问题1&#xff1a; 调用avx是报错 error: inlining failed in call to always_inline ‘__m512…...

18 个JS优化技巧,可以解决 90% 的屎山代码!!!

文章目录 18 个JS优化技巧&#xff0c;可以解决 90% 的屎山代码&#xff01;&#xff01;&#xff01;1.箭头函数2.解构赋值变量3.使用模版字面量进行字符拼接4.使用展开运算符进行数组和对象操作5.简化循环6.简化判断7.使用对象解构和默认参数简化函数参数8.使用函数式编程概念…...

go逆向符号恢复

前言 之前一直没怎么重视&#xff0c;结果发现每次遇到go的题都是一筹莫展&#xff0c;刷几道题练习一下吧 准备 go语言写的程序一般都被strip去掉符号了&#xff0c;而且ida没有相关的签名文件&#xff0c;没办法完成函数名的识别与字符串的定位&#xff0c;所以第一步通常…...

论文阅读- Uncovering Coordinated Networks on Social Media:Methods and Case Studies

链接&#xff1a;https://arxiv.org/pdf/2001.05658.pdf 目录 摘要&#xff1a; 引言 Methods Case Study 1: Account Handle Sharing Coordination Detection 分析 Case Study 2: Image Coordination Coordination Detection Analysis Case Study 3: Hashtag Sequen…...

应急响应-Linux

应急响应-Linux 1.关键目录 /etc/passwd 记录用户信息 /etc/shadow 保存用户密码&#xff08;hash&#xff09; /etc/crontab 定时任务文件 /etc/anacrontab 异步定时任务文件 /etc/rc.d/rc.local 开机启动项 /var/log/btmp …...

利用spinal的伴生对象简化集成rtl代码过程

一 参考 SpinalHDL——集成你的RTL代码 (qq.com)https://mp.weixin.qq.com/s?__biz=Mzg5NjQyMzQwMQ==&mid=2247484852&idx=1&sn=d074279cdc0d58eb5dc73ca68271eee8&chksm=c0000132f77788249838570187495e34cc12ab40e8f8f5ec8f65414ec84b3ece2d17f0d4c4f8&…...

C# Blazor 学习笔记(7):组件嵌套开发

文章目录 前言相关资料组件嵌套组件模板RenderFragment 意义传统前端样式组件化css 前言 我们在组件化一共有三个目的。 不用写CSS不用写html不用写交互逻辑 简单来说就是Java常说的约定大于配置。我们只需要必须的参数即可&#xff0c;其它的都按照默认配置。我们不需要关系…...

DAY1,C高级(命令,Linux的文件系统,软、硬链接文件)

1.创建链接文件&#xff1b; 文件系统中的每个文件都与唯一的 inode 相关联&#xff0c;inode 存储了文件的元数据和数据块的地址&#xff0c;文件名与 inode 之间的链接关系称为硬链接或软链接。 硬链接文件的创建&#xff1a; ln 被链接文件的绝对路径 硬链接文件的绝对…...

Race竞争型漏洞

目录 Race竞争介绍 实验环境配置 安装Cookiecutter 创建基于Django框架的项目 选择配置 创建数据库 加载到环境变量里 数据库的生成 创建一个超级用户&#xff08;superuser&#xff09; 启动一个本地开发服务器 配置文件 Race竞争介绍 竞争型漏洞&#xff08;Race Co…...

基于 FFlogs API 快速实现的 logs 颜色查询小爬虫

文章目录 找到接口解析响应需要平均颜色和过本次数&#xff1f; 找到接口 首先试了一下爬虫&#xff0c;发现和wow一样官网上有暴露的 API&#xff0c;链接在&#xff1a;FFlogs v1 API 文档链接 通过查询官方提供的 API 接口得知&#xff1a; user_name 角色名字 api_key …...

【牛客】统计字符

⭐️ 题目描述 &#x1f31f; OJ链接&#xff1a;HJ40 统计字符 ps&#xff1a; 判断字符可以直接使用头文件自带的函数。 函数作用iscntrl判断是否为控制字符isspace判断是否为空白字符&#xff08;空格、换页’\f’、换行’\n’、回车’\r’、制表符’\t&#xff09;isdigi…...

测试|Junit相关内容

测试|Junit相关内容 文章目录 测试|Junit相关内容0.Junit说明1.Junit注解TestDisabledBeforeAll和AfterAllBeforeEach和AfterEach 2.Junit参数化单参数多参数&#xff08;多种/多组&#xff09;CSV获取参数&#xff08;支持多种&#xff09;CSV文件获取参数&#xff08;支持多种…...

19-2.vuex

目录 1 安装 2 挂载 2.1 vue2写法 2.2 vue3写法 3 state 3.1 声明数据 3.2 使用数据 3.3 处理数据 4 mutations 4.1 基本使用 4.2 传递参数 4.3 mutations中不能写异步的代码 5 actions 5.1 基本使用 5.2 传递参数 6 getters Vuex是做全局数据…...

HPKM-PINN:KAN-MLP并行混合物理信息神经网络技术 第1章 KAN基础与MLP局限的理论分析(二)

脚本 2.1.2.2:激活函数选择——Tanh 与 SwiGLU 在物理约束中的适应性 涉及内容:对比分析 Tanh 与 SwiGLU 激活函数在物理信息神经网络中的适应性,验证不同物理约束(如边界条件、守恒律)下的数值稳定性。 使用方式:运行脚本生成激活函数特性对比、物理约束满足度分析及梯…...

接口测试--Day5

Pytest是一个流行的测试框架&#xff0c;广泛应用于单元测试、集成测试和功能测试。它具有简单、灵活、可扩展的特点&#xff0c;提供了丰富的功能和插件儿生态系统&#xff0c;它简化了测试的编写和组织拍&#xff0c;通过丰富的功能和简洁的语法&#xff0c;让测试变得容易灵…...

Nunchaku FLUX.1-dev实战:手把手教你用ComfyUI生成惊艳AI图片

Nunchaku FLUX.1-dev实战&#xff1a;手把手教你用ComfyUI生成惊艳AI图片 1. 环境准备与快速部署 1.1 硬件与软件要求 在开始之前&#xff0c;请确保你的系统满足以下基本要求&#xff1a; 显卡&#xff1a;NVIDIA显卡&#xff08;推荐RTX 30/40系列&#xff0c;显存8GB&am…...

如何突破B站视频获取限制?这款开源工具让你轻松搞定

如何突破B站视频获取限制&#xff1f;这款开源工具让你轻松搞定 【免费下载链接】bilibili-parse bilibili Video API 项目地址: https://gitcode.com/gh_mirrors/bi/bilibili-parse 你是否遇到过想要保存B站精彩视频却无从下手的困境&#xff1f;是否因复杂的技术门槛而…...

Pixel Aurora Engine镜像部署:多用户并发生成的Streamlit服务配置

Pixel Aurora Engine镜像部署&#xff1a;多用户并发生成的Streamlit服务配置 1. 像素极光引擎简介 Pixel Aurora&#xff08;像素极光&#xff09;是一款基于AI扩散模型的高端绘图工作站&#xff0c;采用独特的复古像素游戏风格界面设计。这款工具能够将文字描述转化为极具视…...

LPDDR4X引脚功能详解:从CK到DQS,这些信号线你都用对了吗?

LPDDR4X引脚功能深度解析&#xff1a;信号完整性设计与实战避坑指南 在移动设备和高性能嵌入式系统中&#xff0c;LPDDR4X内存已成为主流选择。但许多硬件工程师在实际设计中常陷入"信号连通即可"的误区&#xff0c;导致系统稳定性问题频发。本文将带您深入理解每个…...

15 分钟上线|开源克隆网站 + 一键部署,搭建你自己的产品

把目标网站像素级克隆下来&#xff0c;再用部署技能把它一键部署到线上。全程主要靠自然语言对话完成&#xff0c;不需要命令行操作&#xff0c;不需要懂代码。你要做的只有一件事&#xff1a;把“你想复制哪个网站、要怎么上线”说清楚&#xff0c;其它交给 AI 去检测、拆解、…...

QMCDecode:让音乐自由播放的开源格式转换工具

QMCDecode&#xff1a;让音乐自由播放的开源格式转换工具 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac&#xff0c;qmc0,qmc3转mp3, mflac,mflac0等转flac)&#xff0c;仅支持macOS&#xff0c;可自动识别到QQ音乐下载目录&#xff0c;默认转换结果存…...

革新性英雄联盟智能辅助解决方案:一站式游戏体验提升工具

革新性英雄联盟智能辅助解决方案&#xff1a;一站式游戏体验提升工具 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 在快节奏的英…...

GyroFlow:用陀螺仪数据重塑视频稳定技术

GyroFlow&#xff1a;用陀螺仪数据重塑视频稳定技术 【免费下载链接】gyroflow Video stabilization using gyroscope data 项目地址: https://gitcode.com/GitHub_Trending/gy/gyroflow 在数字影像创作领域&#xff0c;画面稳定性直接决定作品专业度。无论是运动相机拍…...