SpringBoot项目集成MinIO
一、MinIO的下载安装以及基本使用
1.下载地址:https://dl.min.io/server/minio/release/windows-amd64/minio.exe
2.下载好后需要手动创建data文件夹用于存储MinIO中的数据
3.键入cmd

4. 设置MinIO的一些变量(第一次启动需要配置)
set MINIO_ROOT_USER=admin set MINIO_ROOT_PASSWORD=admin123 set MINIO_ACCESS_KEY=admin set MINIO_SECRET_KEY=admin123
5.下面是我踩的坑,如果只设置了MINIO_ROOT_USER和MINIO_ROOT_PASSWORD的值,而不设置MINIO_ACCESS_KEY和MINIO_SECRET_KEY的值,当启动minio服务的时候就会报以下异常:

所以一定要设置好后面两个变量的值。
6. 启动minio服务
minio.exe server data

7.进入登录页面后,输入对应的用户名和密码,也就是之前设置的MINIO_ROOT_USER和MINIO_ROOT_PASSWORD的值。

8. 进入主界面后,点击左侧导航栏中的Buckets,然后点击Create Bucket。

9.进入该桶,点击upload,上传一个文件,桶的默认权限是private,所以外界访问不到,需要修改访问权限为public,但是要注意安全问

点击左侧导航栏中的Buckets,进入该桶,修改权限为public,这样外界就可以访问上传的文件了。

二. SpringBoot集成MinIO
1.引入依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.0.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
2.编写配置文件
server:
port: 8080
spring:
# 配置文件上传大小限制
servlet:
multipart:
max-file-size: 200MB
max-request-size: 200MB
minio:
host: http://127.0.0.1:9000 # 访问地址
url: ${minio.host}/${minio.bucket}/ # 对象存储服务的url
access-key: minioadmin # 登录账号
secret-key: minioadmin # 登录账号密码
bucketName: test-bucket # 文件桶的名称
bucket: public // 权限
3.编写minio配置类
@Configuration
public class MinIoClientConfig {
/**
* minio配置
*/
@Value("${minio.url}")
private String endpoint;
@Value("${minio.accessKey}")
private String accessKey;
@Value("${minio.secretKey}")
private String secretKey;
@Value("${minio.bucketName}")
private String bucketName; /**
* 注入minio客户端
*
* @return minio客户端对象
*/
@Bean
public MinioClient minioClient() {
return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
}
}
4.编写minio工具类
@Component
public class MinioUtil { /**
* minio配置
*/
@Value("${minio.url}")
private String endpoint; @Autowired
private MinioClient minioClient; /**
* 创建一个桶
*/
public void createBucket(String bucket) throws Exception {
boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
if (!found) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
}
} /**
* 上传一个文件
*/
public void uploadFile(InputStream stream, String bucket, String objectName) throws Exception {
ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName)
.stream(stream, -1, 10485760).build()); System.out.println(objectWriteResponse.object() + " is uploaded successfully.");
} /**
* 列出所有的桶
*/
public List<String> listBuckets() throws Exception {
List<Bucket> list = minioClient.listBuckets();
List<String> names = new ArrayList<>();
list.forEach(b -> {
names.add(b.name());
});
return names;
} /**
* 列出一个桶中的所有文件和目录
*/
public List<Fileinfo> listFiles(String bucket) throws Exception {
Iterable<Result<Item>> results = minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucket).recursive(true).build()); List<Fileinfo> infos = new ArrayList<>();
results.forEach(r->{
Fileinfo info = new Fileinfo();
try {
Item item = r.get();
info.setFilename(item.objectName());
info.setDirectory(item.isDir());
info.setFilepath(endpoint+"/"+bucket+"/"+item.objectName());
infos.add(info);
} catch (Exception e) {
e.printStackTrace();
}
});
return infos;
} /**
* 下载一个文件
*/
public InputStream download(String bucket, String objectName) throws Exception {
InputStream stream = minioClient.getObject(
GetObjectArgs.builder().bucket(bucket).object(objectName).build());
return stream;
} /**
* 删除一个桶
*/
public void deleteBucket(String bucket) throws Exception {
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build());
} /**
* 删除一个对象
*/
public void deleteObject(String bucket, String objectName) throws Exception {
minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectName).build());
} /**
* 复制文件
*/
public void copyObject(String sourceBucket, String sourceObject, String targetBucket, String targetObject) throws Exception {
this.createBucket(targetBucket);
minioClient.copyObject(CopyObjectArgs.builder().bucket(targetBucket).object(targetObject)
.source(CopySource.builder().bucket(sourceBucket).object(sourceObject).build()).build());
} /**
* 获取文件信息
*/
public String getObjectInfo(String bucket, String objectName) throws Exception {
return minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(objectName).build()).toString(); } /**
* 生成一个给HTTP GET请求用的presigned URL。
* 浏览器/移动端的客户端可以用这个URL进行下载,
* 即使其所在的存储桶是私有的。
*/
public String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) throws Exception {
GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs
.builder().bucket(bucketName).object(objectName).expiry(expires).method(Method.GET).build();
return minioClient.getPresignedObjectUrl(build);
} /**
* 获取minio中所有的文件
*/
public List<Fileinfo> listAllFile() throws Exception {
List<String> list = this.listBuckets();
List<Fileinfo> fileinfos = new ArrayList<>();
for (String bucketName : list) {
fileinfos.addAll(this.listFiles(bucketName));
}
return fileinfos;
}
}
5.编写文件实体类
@Data
public class Fileinfo {
String filename;
String filepath;
Boolean directory;
}
6.编写接口响应实体
@Data
public class ResultData<T> { public static final Integer SUCCESS_CODE = 200;
public static final Integer FAIL_CODE = 4000;
public static final String SUCCESS_MESSAGE = "操作成功";
public static final String FAIL_MESSAGE = "操作失败";
/**
* 返回状态码
*/
private Integer code;
/**
* 返回信息
*/
private String message; /**
* 返回数据
*/
private T data; public ResultData() { } public static <T> ResultData<T> success() {
ResultData<T> resultUtil = new ResultData<>();
resultUtil.setCode(SUCCESS_CODE);
resultUtil.setMessage(SUCCESS_MESSAGE);
return resultUtil;
} public static <T> ResultData<T> success(T data) {
ResultData<T> resultUtil = success();
resultUtil.setData(data);
return resultUtil;
} public static <T> ResultData<T> success(String message, T data) {
ResultData<T> resultUtil = success();
resultUtil.setMessage(message);
resultUtil.setData(data);
return resultUtil;
} public static <T> ResultData<T> success(Integer code, String message, T data) {
ResultData<T> resultUtil = new ResultData<>();
resultUtil.setCode(code);
resultUtil.setMessage(message);
resultUtil.setData(data);
return resultUtil;
} public static <T> ResultData<T> success(Integer code, String message,Integer count, T data) {
ResultData<T> resultUtil = new ResultData<>();
resultUtil.setCode(code);
resultUtil.setMessage(message);
resultUtil.setData(data);
return resultUtil;
} public static <T> ResultData<T> fail() {
ResultData<T> resultUtil = new ResultData<>();
resultUtil.setCode(FAIL_CODE);
resultUtil.setMessage(FAIL_MESSAGE);
return resultUtil;
} public static <T> ResultData<T> fail(T data) {
ResultData<T> resultUtil = fail();
resultUtil.setData(data);
return resultUtil;
} public static <T> ResultData<T> fail(String message, T data) {
ResultData<T> resultUtil = fail();
resultUtil.setMessage(message);
resultUtil.setData(data);
return resultUtil;
} public static <T> ResultData<T> fail(Integer code, String message) {
ResultData<T> resultUtil = fail();
resultUtil.setCode(code);
resultUtil.setMessage(message);
return resultUtil;
} public static <T> ResultData<T> fail(Integer code, String message, T data) {
ResultData<T> resultUtil = new ResultData<>();
resultUtil.setCode(code);
resultUtil.setMessage(message);
resultUtil.setData(data);
return resultUtil;
} public void setCode(int code){
this.code = code;
}
public int getCode(){
return this.code;
}
public void setMessage(String message){
this.message = message;
}
public String getMessage(){
return message;
}
public void setData(T data){
this.data = data;
}
public T getData(){
return data;
}
}
7.创建minio控制器
/**
* minio相关接口
*
* @author songwp
* @date 2024/11/11 11:28
*/
@RestController
@RequestMapping("minio")
public class MinioController { @Autowired
MinioUtil minioUtil; /**
* 文件上传
*
* @param file 文件
* @param bucket 桶名
* @param objectName 对象名
* @return 是否成功
* @throws Exception
*/
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public ResultData upload(@RequestParam MultipartFile file,
@RequestParam String bucket,
@RequestParam(required = false) String objectName) throws Exception {
minioUtil.createBucket(bucket);
if (objectName != null) {
minioUtil.uploadFile(file.getInputStream(), bucket, objectName + "/" + file.getOriginalFilename());
} else {
minioUtil.uploadFile(file.getInputStream(), bucket, file.getOriginalFilename());
}
return ResultData.success();
} /**
* 获取文件信息
* @param bucket 桶名
* @return 是否成功
*/
@RequestMapping(value = "/getFile", method = RequestMethod.GET)
public ResultData getFile(@RequestParam ("bucket")String bucket){
try {
List<Fileinfo> fileinfos = minioUtil.listFiles(bucket);
return ResultData.success(fileinfos);
} catch (Exception e) {
throw new RuntimeException(e);
}
} /**
* 文件下载
*
* @param bucket 桶名
* @param objectName 对象名
* @return 是否成功
*/
@GetMapping("download")
public ResultData download(@RequestParam("bucket") String bucket,
@RequestParam("objectName") String objectName){
try {
InputStream download = minioUtil.download(bucket, objectName);
return ResultData.success();
} catch (Exception e) {
throw new RuntimeException(e);
}
} /**
* 获取文件信息
*
* @param bucket 桶名
* @param objectName 对象名
* @return 是否成功
*/
@GetMapping("getObjectInfo")
public ResultData getObjectInfo(@RequestParam("bucket") String bucket,
@RequestParam("objectName") String objectName) throws Exception {
String objectInfo = minioUtil.getObjectInfo(bucket, objectName);
String objectStat = objectInfo.replaceAll("ObjectStat", "");
return ResultData.success(objectStat);
} /**
* 生成一个给HTTP GET请求用的presigned URL。
*
* @param bucket 桶名
* @param objectName 对象名
* @return 是否成功
*/
@GetMapping("getObjectUrl")
public ResultData getObjectUrl(@RequestParam("bucket") String bucket,
@RequestParam("objectName") String objectName) throws Exception {
String url = minioUtil.getPresignedObjectUrl(bucket, objectName,7200);
return ResultData.success(url);
} /**
* 列出所有的桶
*/
@RequestMapping(value = "/listBuckets", method = RequestMethod.GET)
public ResultData listBuckets() throws Exception {
return ResultData.success(minioUtil.listBuckets());
} /**
* 获取minio中所有的文件
*/
@RequestMapping(value = "/listAllFile", method = RequestMethod.GET)
public ResultData listAllFile() throws Exception {
return ResultData.success(minioUtil.listAllFile());
}
}
8.postman接口调用实例

9.最后查看test-bucket桶中是否有刚才上传的文件就可以了。如果有则表明你的项目已经成功集成minio了

SpringBoot项目集成MinIO的更多相关文章
- SpringBoot项目集成Hystrix
Hystrix Hystrix是由Netflix开源的一个服务隔离组件,通过服务隔离来避免由于依赖延迟.异常,引起资源耗尽导致系统不可用的解决方案. 1.什么是服务熔断 服务熔断就是对该服务的调用 ...
- SpringBoot项目集成PageHelper使用
SpringBoot项目集成PageHelper使用 一.开始 地址:https://github.com/pagehelper/Mybatis-PageHelper 在spring boot ...
- 七、SpringBoot项目集成JSP以及项目不同启动方式及访问路径配置
1.创建JSP目录 在src/main目录下创建目录webapp/WEB-INF/jsp用于存放jsp页面,如下图: 然后再改文件夹下面我们创建JSP文件: 大家在使用IDEA 的new菜单创建JSP ...
- springboot项目集成activity
1.按照上一篇博客,新建好springboot项目后,在项目pom.xml文件中添加activity依赖 <dependency> <groupId>org.activiti& ...
- Springboot项目集成JPush极光推送(Java SDK)
1.由于项目的需求,需要在Android APP上实现消息推送功能,所以引用了极光推送(官网:https://www.jiguang.cn/, 文档:http://docs.jiguang.cn/) ...
- 使用IDEA快速搭建基于Maven的SpringBoot项目(集成使用Redis)
迫于好久没写博客心慌慌,随便写个简单版的笔记便于查阅. 新建项目 新建项目 然后起名 继续next netx finish. 首先附上demo的项目结构图 配置pom.xml <?xml ver ...
- ElasticSearch(九):springboot项目集成消息中间件activeMQ
目的:为了将elasticsearch做成单独的服务,那么我们必须解耦,也就是业务逻辑和搜索模块是没有关系的,并且是异步的.那么项目之间通信,使用的选择有限,消息中间件是一个不错的选择. 消息中间件常 ...
- SpringBoot项目集成socketIo实现实时推送
netty-socketio maven依赖 <dependency> <groupId>com.corundumstudio.socketio</groupId> ...
- SpringBoot项目集成cas单点登录
添加依赖 添加cas client依赖 <dependency> <groupId>net.unicon.cas</groupId> <artifactId& ...
- SpringBoot项目集成Redis
一.在pom文件中添加依赖 <!-- 集成redis --> <dependency> <groupId>org.springframework.boot</ ...
随机推荐
- AC自动机 基础篇
AC 自动机1 前置知识:\(KMP\),字典树. \(AC\) 自动机,不是用来自动 \(AC\) 题目的,而是用来处理字符串问题的(虽然确实可以帮助你 \(AC\)). 这里总结了 \(AC\) ...
- 20-canvas之形变
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...
- python3安装虚拟环境并使用freeze命令迁移模块
python3安装虚拟环境 #1.安装虚拟环境 pip3 install virtualenv #2.创建虚拟环境 python3 -m venv venv #或者 python3 -m venv . ...
- TimeWheel算法介绍及在应用上的探索
作者:来自 vivo 互联网服务器团队- Li Fan 本文从追溯时间轮算法的出现,介绍了时间轮算法未出现前,基于队列的定时任务实现,以及基于队列的定时任务实现所存在的缺陷.接着我们介绍了时间轮算法的 ...
- AWS Data Analytics Fundamentals 官方课程笔记 - Variety, Veracity, Value
Variety structured data applications include Amazon RDS, Amazon Aurora, MySQL, MariaDB, PostgreSQL, ...
- 6.24Win&linux&分析后门 勒索病毒分析
操作系统应急响应 1.常见危害 暴力破解.漏洞利用.流量攻击(危害不确定) 木马控制(Webshell.PC木马等),病毒感染(挖矿.蠕虫.勒索等) 2.常见分析 计算机用户.端口.进程.启动项.计划 ...
- 如何发布一个Vue组件到Npm上?
前端时间做了一个基于Vue的拼图验证组件,因为公司需要,就想着做完之后放到Npm上,方便使用 发布流程如下: 1. 创建一个Npm账号并进行邮箱确认(很重要) 2. 创建一个文件夹,然后 npm in ...
- ServiceMesh 1:大火的云原生微服务网格,究竟好在哪里?
1 关于云原生 云原生计算基金会(Cloud Native Computing Foundation, CNCF)的官方描述是: 云原生是一类技术的统称,通过云原生技术,我们可以构建出更易于弹性扩展. ...
- JS之Math.sin与Math.cos介绍及应用-实现鼠标点击后的烟花效果
基本介绍 Math.sin(x) :x 的正玄值.返回值在 -1.0 到 1.0 之间: Math.cos(x) :x 的余弦值.返回的是 -1.0 到 1.0 之间的数: 其中函数中是x是指&quo ...
- 三牧校队训练题目 Solution
前置知识: 搜索 队列 栈 递归 (提高难度)记忆化搜索 T1:P1226 [模板]快速幂 暴力想法:\(a\times a\) 进行 \(b\) 次,每次 \(a\times a\mod p\). ...