一、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的更多相关文章

  1. SpringBoot项目集成Hystrix

    Hystrix Hystrix是由Netflix开源的一个服务隔离组件,通过服务隔离来避免由于依赖延迟.异常,引起资源耗尽导致系统不可用的解决方案. 1.什么是服务熔断   服务熔断就是对该服务的调用 ...

  2. SpringBoot项目集成PageHelper使用

    SpringBoot项目集成PageHelper使用 一.开始 ​ 地址:https://github.com/pagehelper/Mybatis-PageHelper ​ 在spring boot ...

  3. 七、SpringBoot项目集成JSP以及项目不同启动方式及访问路径配置

    1.创建JSP目录 在src/main目录下创建目录webapp/WEB-INF/jsp用于存放jsp页面,如下图: 然后再改文件夹下面我们创建JSP文件: 大家在使用IDEA 的new菜单创建JSP ...

  4. springboot项目集成activity

    1.按照上一篇博客,新建好springboot项目后,在项目pom.xml文件中添加activity依赖 <dependency> <groupId>org.activiti& ...

  5. Springboot项目集成JPush极光推送(Java SDK)

    1.由于项目的需求,需要在Android APP上实现消息推送功能,所以引用了极光推送(官网:https://www.jiguang.cn/, 文档:http://docs.jiguang.cn/) ...

  6. 使用IDEA快速搭建基于Maven的SpringBoot项目(集成使用Redis)

    迫于好久没写博客心慌慌,随便写个简单版的笔记便于查阅. 新建项目 新建项目 然后起名 继续next netx finish. 首先附上demo的项目结构图 配置pom.xml <?xml ver ...

  7. ElasticSearch(九):springboot项目集成消息中间件activeMQ

    目的:为了将elasticsearch做成单独的服务,那么我们必须解耦,也就是业务逻辑和搜索模块是没有关系的,并且是异步的.那么项目之间通信,使用的选择有限,消息中间件是一个不错的选择. 消息中间件常 ...

  8. SpringBoot项目集成socketIo实现实时推送

    netty-socketio maven依赖 <dependency> <groupId>com.corundumstudio.socketio</groupId> ...

  9. SpringBoot项目集成cas单点登录

    添加依赖 添加cas client依赖 <dependency> <groupId>net.unicon.cas</groupId> <artifactId& ...

  10. SpringBoot项目集成Redis

    一.在pom文件中添加依赖 <!-- 集成redis --> <dependency> <groupId>org.springframework.boot</ ...

随机推荐

  1. Vue-方法与事件

    基本用法 监听点击事件 v-on 缩写:@ 预期:Function | Inline Statement | Object 参数:event 修饰符: .stop - 调用 event.stopPro ...

  2. 神经网络之卷积篇:详解卷积步长(Strided convolutions)

    详解卷积步长 卷积中的步幅是另一个构建卷积神经网络的基本操作,让向展示一个例子. 如果想用3×3的过滤器卷积这个7×7的图像,和之前不同的是,把步幅设置成了2.还和之前一样取左上方的3×3区域的元素的 ...

  3. Namomo Summer Camp 23 Day 1(GCPC2021)

    Namomo Summer Camp 23 Day 1(GCPC2021) Problem B: Brexiting and Brentering 签到 #include<bits/stdc++ ...

  4. bx lr

    bx lr 的作用等同于 mov pc,lr 即跳转到lr中存放的地址处. 那么lr存放的是什么地址呢? lr就是连接寄存器(Link Register, LR),在ARM体系结构中LR的特殊用途有两 ...

  5. 2023 ICPC 香港

    gym 开场发现 E 是传统数据结构题很高兴,不过先跳了.F 知道相邻两段的长度差 \(\le1\),以为最终每段长度只有 \(\lfloor\frac{n}{m+1}\rfloor,\lceil\f ...

  6. 解决 Rust WebAssembly 启动 Web 程序报错

    当你艰难入门 Rust ,并满怀斗志准备投身 WebAssembly,第一课也许会先给你泼盆凉水. 跟随 <Rust 和 WebAssembly> 文档的指引,一路 install.cod ...

  7. 每天那么多工作,我为什么能做到 "不忘事" ?

    大家好,我是程序员鱼皮. 我相信很多朋友都遇到过丢失工作.或者忘记事情的情况,尤其是事情一多,就更容易遗漏:而如果在工作中你漏掉了某项任务,需要上级或同事重复提醒你,是很影响别人对你的印象的. 那么如 ...

  8. Mac 使用远程 Ubuntu 机器进行时间备份

    设置 SMB 服务 首先在 Ubuntu 中配置 SMB 服务.可以参考 Ubuntu 设置 SMB 服务. 创建 APFS 磁盘映像 我们在 Ubuntu 上创建出的 SMB 共享文件夹可以用来存放 ...

  9. 【Docker】之重启容器相关命令

    我想每次打开电脑,只要自动运行docker的时候,马上把设置指定的容器也自动运行起来. 首先查看一下容器启动情况: # 查看docker运行命令 docker ps -a --restart参数有3个 ...

  10. python 读取mysqlDB中指定的表名的DDL语句

    注意: 1. 此python文件不要起名为mysql,会跟import的包名重复,python mysql.py运行报错 2.如果需要带端口号,请加database后加上, port="33 ...