✨重磅!盹猫的个人小站正式上线啦~诚邀各位技术大佬前来探秘!✨
这里有:
- 硬核技术干货:编程技巧、开发经验、踩坑指南,带你解锁技术新姿势!
- 趣味开发日常:代码背后的脑洞故事、工具测评,让技术圈不再枯燥~
- 独家资源分享:开源项目、学习资料包,助你打怪升级快人一步!
👉 点击直达→ 盹猫猫的个人小站 👈
🌟 来逛逛吧,说不定能挖到你正在找的技术宝藏哦~
目录
[🎁 前言](#🎁 前言)
[⬇️ 下载运行minio](#⬇️ 下载运行minio)
[🌲 环境准备](#🌲 环境准备)
[🐴 代码步骤](#🐴 代码步骤)
[⚙️ 配置文件](#⚙️ 配置文件)
[⚙️ 配置类](#⚙️ 配置类)
[🔧 工具类](#🔧 工具类)
[1️⃣ 注入MinioClient](#1️⃣ 注入MinioClient)
[2️⃣ 上传图片](#2️⃣ 上传图片)
[3️⃣ 删除文件](#3️⃣ 删除文件)
[4️⃣ 获取临时文件链接](#4️⃣ 获取临时文件链接)
[5️⃣ 设置桶目录访问权限](#5️⃣ 设置桶目录访问权限)
[❓ 疑问解答](#❓ 疑问解答)
[⭐ 如何使用nginx进行代理minio配置?](#⭐ 如何使用nginx进行代理minio配置?)
[⭕ 总结](#⭕ 总结)
欢迎来到 盹猫(>^ω^<)的博客
本篇文章主要介绍了
**SpringBoot从0-1集成Minio对象存储**
❤博主广交技术好友,喜欢文章的可以关注一下❤
🎁 前言
在SpringBoot开发过程中,上传一些图片、视频资源是经常用到的功能需求,比如说头像上传,身份证信息上传,视频文件上传等。但这些上传之间存在着一些差别,比如说头像图片(一般会作为公开数据),其它用户是可以看到你的头像。而身份证图片一般是私有数据,不希望其它人可以查看你的身份证信息。
这时如果将上传的图片放到公开的容器(如:tomcat)是不合适的,那怎么解决这个问题呢?
解决方法就是**部署并集成oss对象存储系统 ,**而经常用到的就是minio对象存储服务。本篇就是记录SpringBoot如何集成minio对象存储系统,但在此之前先看下minio是什么。
🤔 什么是minio对象存储系统?
MinIO 是一款开源的、高性能的对象存储服务器,兼容 Amazon S3(Simple Storage Service)API 接口,专为海量非结构化数据(如图片、视频、日志文件、备份数据、容器镜像等)设计,可部署在私有云、公有云、边缘设备等多种环境中。
废话不多说,让我们看看如何集成吧!
Let's GO!
⬇️ 下载运行minio
当然第一步肯定是需要下载并运行minio服务,方法很简单,以Windows为例,可以点击下方的链接进行下载:
https://dl.min.io/server/minio/release/windows-amd64/minio.exe
当然,可以选择release路径下选择不同的系统环境进行下载。
下载完成后,在minio.exe所在目录通过cmd命令行运行下面的命令:
bash
./minio.exe server ./data --console-address ":9001" --address ":8972"
--console-address ":9001" : 表示控制台运行在9001端口。
--address ":8972":表示可以通过8972进行S3服务的调用,即在SpringBoot中主要用到这个端口调用API访问。
上述端口可根据实际需要进行修改配置。
运行后可在浏览器访问本机的9001端口,出现如图界面:

默认用户名和密码均为minioadmin,登录后进行管理界面,根据需求创建一个bucket(容器桶)。

🌲 环境准备
在Pom文件中引入下述minio依赖,集成官方的SDK,这可以使我们方便的调用MinioClient类进行文件上传等操作,依赖如下:
XML
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.4.3</version>
</dependency>
🐴 代码步骤
⚙️ 配置文件
在springboot的yml文件中添加下述依赖配置,这会在后面的配置类中使用,其中包括minio服务URL(即S3服务接口8972),公钥(登录的用户名),密钥(登录的密码),桶名称(创建的bucket名称),如下:
java
minio:
endpoint: minio服务url
access-key: 公钥
secret-key: 密钥
bucket-name: 存储桶的名称
⚙️ 配置类
创建一个配置类,该类用于创建MinioClient,并交与SpringBoot管理,这样在后续的编码过程中就可以注入使用了,代码如下:
java
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.MalformedURLException;
/**
* minio配置类
* @author nodcat
* @version 1.0
* @since 2025/12/20 上午9:52
*/
@Configuration
public class MinioConfig {
@Value("${minio.endpoint}")
private String endpoint;
@Value("${minio.access-key}")
private String accessKey;
@Value("${minio.secret-key}")
private String secretKey;
@Bean
public MinioClient minioClient() throws MalformedURLException {
return MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
}
}
🔧 工具类
1️⃣ 注入MinioClient
在工具类中,需要注入自定义的MinioClient和桶名称,用于在方法中对实际的桶进行操作,代码如下:
java
private final MinioClient minioClient;
@Value("${minio.bucket-name}")
private String bucketName;
// 构造器注入 MinioClient
public MinioUtil(MinioClient minioClient) {
this.minioClient = minioClient;
}
2️⃣ 上传图片
在上传文件时,只需要设置桶名称、远程的对象名称(如果是路径+名称,则会自动创建目录)、输入流、文件类型,如这里的代码会在桶内创建一个images目录,且使用上传的文件的sha256hex作为文件名,代码如下:
java
/**
* 上传文件
* @param file 待上传的文件
* @return 文件在 MinIO 中的存储路径
*/
public String uploadImage(MultipartFile file) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
String originalFilename = file.getOriginalFilename();
// 获取文件扩展名
String extension = FilenameUtils.getExtension(originalFilename);
String md5;
try (InputStream inputStream = file.getInputStream()) {
hex256 = DigestUtils.sha256Hex(inputStream).toLowerCase();
}
//目录和名称
String objectName = "images/" + hex256 + "." + extension;
try (InputStream inputStream = file.getInputStream()) {
minioClient.putObject(
PutObjectArgs.builder()
//设置桶名称
.bucket(bucketName)
//对象名称
.object(objectName)
//输入流
.stream(inputStream, file.getSize(), -1)
//文件类型
.contentType(file.getContentType())
.build()
);
}
return objectName;
}
上传完成后即可在控制台看到创建的目录和上传的文件,如下:

3️⃣ 删除文件
删除文件时就更简单了,直接设置好桶名称和对象名称,并调用**removeObject()**方法即可,代码如下:
java
/**
* 删除文件
* @param objectName 文件在 MinIO 中的存储路径
*/
public void deleteFile(String objectName) throws io.minio.errors.ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
// 先判断文件是否存在
minioClient.statObject(
StatObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build()
);
// 删除文件
minioClient.removeObject(
RemoveObjectArgs.builder()
//桶名称
.bucket(bucketName)
//对象名称
.object(objectName)
.build()
);
}
4️⃣ 获取临时文件链接
生成临时文件链接可以实现文件的私有性访问,使用getPresignedObjectUrl方法并设置获取方式、桶名称、对象名称、超时时间,即可生成具有时效性的图片/文件的访问链接,这在存储一些用户隐私数据时很有用(比如身份证信息),代码如下:
java
/**
* 获取文件临时访问链接
* @param objectName MinIO 存储的对象名(如:images/9e107d9d372bb6826bd81d3542a419d6.jpg)
* @param expireSeconds 链接有效期(秒),如 3600 = 1小时
* @return 临时访问链接
*/
public String getPreSignedUrl(String objectName, int expireSeconds) throws Exception {
// 生成GET方法的临时签名链接
return minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
//可以使用GET获取
.method(Method.GET)
//桶名称设置
.bucket(bucketName)
//对象名称设置
.object(objectName)
//超时时间
.expiry(expireSeconds)
.build()
);
}
生成链接格式如下:
5️⃣ 设置桶目录访问权限
创建的目录默认为私有访问权限,若需要将其设定为公开访问权限可以setBucketPolicy方法对桶策略进行设置,代码如下:
java
/**
* 将指定桶路径配置为「公开读权限」(匿名用户可访问所有文件)
* @throws Exception 配置失败时抛出异常
*/
public void setBucketPublicRead(String path) throws Exception {
// 1. 构造桶策略 JSON:允许所有匿名用户读取桶内所有对象
JSONObject policyJson = new JSONObject();
policyJson.put("Version", "2012-10-17");
// 策略声明:仅允许 GetObject(读文件),禁止 ListBucket(列文件)
JSONObject statement = new JSONObject();
statement.put("Effect", "Allow");
statement.put("Principal", "*");
statement.put("Action", "s3:GetObject");
// 资源范围:该桶下的所有对象(/* 表示桶内所有文件)
statement.put("Resource", "arn:aws:s3:::" + bucketName + "/"+path);
policyJson.put("Statement", new JSONObject[]{statement});
// 2. 应用桶策略
minioClient.setBucketPolicy(
SetBucketPolicyArgs.builder()
.bucket(bucketName)
.config(policyJson.toJSONString())
.build()
);
System.out.println("桶 " + bucketName+"/"+path+"已配置为公开读权限!");
}
这里如果传入images/* ,则通过公开链接就可以直接访问某个目录,链接格式如下:
❓ 疑问解答
⭐ 如何使用nginx进行代理minio配置?
使用下面的配置,即可实现nginx对对minio服务进行代理,内容如下:
java
# API接口代理配置
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 300;
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://192.168.0.184:8972;
}
# Web界面代理配置(含静态资源修正)
location /minio-web/ {
rewrite ^/minio-web/(.*) /$1 break;
proxy_pass http://192.168.0.184:9001/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
# WebSocket支持配置
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 静态资源路径修正
sub_filter '<base href="/"/>' '<base href="/minio-web/"/>';
sub_filter_once off;
}
其中web管理界面可以使用/minio-web/路径进行转发,但是S3接口不能使用带路径的访问格式,必须直接用根路径进行端口映射。
⭕ 总结
可以看出,通过让SpringBoot去集成Minio即可很容易的实现文件和访问权限管理,并且Minio SDK进行了一些标准化的构造器,简化了开发流程。文章只是对一些操作代码进行举例,还有很多其它的操作等待你去探索,快去动手试试吧!
上面就是所有文章内容了,如果内容对你有帮助,麻烦留一个赞👍和收藏⭐支持一下!
如果你对区块链 内容感兴趣可以查看我的专栏:小试牛刀-区块链
感谢您的关注和收藏!!!!!!
