# SpringBoot+MinIO **Repository Path**: unix_xiaobin/spring-boot-minio ## Basic Information - **Project Name**: SpringBoot+MinIO - **Description**: SpringBoot集成minio实现文件的上传,下载,获取列表,增加桶等的基本操作 - **Primary Language**: Java - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 69 - **Created**: 2025-04-23 - **Last Updated**: 2025-04-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # !!安装教程!! 没有安装minio的,请看安装教程:[Linux安装MinIO(图文解说详细版)](https://masiyi.blog.csdn.net/article/details/121336618) # !!最新springboot版本!! 趁着无聊,写了一个minio-spring-boot-starter给大家使用 https://blog.csdn.net/csdnerM/article/details/137999933 [如果嫌麻烦,直接使用Springboot的Starter](https://mvnrepository.com/artifact/io.gitee.wangfugui-ma/minio-spring-boot-starter) ![img.png](READMEimg/img.png) ## !!接口列表!! [http://localhost:8080/swagger-ui.html](http://localhost:8080/swagger-ui.html) ![img.png](READMEimg/img2.png) 用**springboot集成minio**首先介绍一下什么是minio: ***minio是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。*** ## 第一步,我们导入minio的jar包 ```xml io.minio minio 8.2.0 ``` ## 第二步,编写配置类 ```java package com.wangfugui.apprentice.config; 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.accessKey}") private String accessKey; @Value("${minio.secretKey}") private String secretKey; @Bean public MinioClient getMinioClient() { return MinioClient.builder().endpoint(url) .credentials(accessKey, secretKey).build(); } } ``` 这一步的目的是将MinioClient 给注入到spring的容器中以供我们使用 ## 第三步,编写util类 ```java package com.wangfugui.apprentice.common.util; import com.wangfugui.apprentice.dao.dto.Fileinfo; import io.minio.BucketExistsArgs; import io.minio.CopyObjectArgs; import io.minio.CopySource; import io.minio.GetObjectArgs; import io.minio.GetPresignedObjectUrlArgs; import io.minio.ListObjectsArgs; import io.minio.MakeBucketArgs; import io.minio.MinioClient; import io.minio.PutObjectArgs; import io.minio.RemoveBucketArgs; import io.minio.RemoveObjectArgs; import io.minio.Result; import io.minio.StatObjectArgs; import io.minio.http.Method; import io.minio.messages.Bucket; import io.minio.messages.Item; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.InputStream; import java.util.ArrayList; import java.util.List; @Component public class MinioUtil { @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 { minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName) .stream(stream, -1, 10485760).build()); } /** * 列出所有的桶 */ public List listBuckets() throws Exception { List list = minioClient.listBuckets(); List names = new ArrayList<>(); list.forEach(b -> { names.add(b.name()); }); return names; } /** * 列出一个桶中的所有文件和目录 */ public List listFiles(String bucket) throws Exception { Iterable> results = minioClient.listObjects( ListObjectsArgs.builder().bucket(bucket).recursive(true).build()); List infos = new ArrayList<>(); results.forEach(r->{ Fileinfo info = new Fileinfo(); try { Item item = r.get(); info.setFilename(item.objectName()); info.setDirectory(item.isDir()); 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()); } /** * 复制文件 * * @Param: [sourceBucket, sourceObject, targetBucket, targetObject] * @return: void * @Author: MrFugui * @Date: 2021/11/15 */ 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()); } /** * 获取文件信息 * * @Param: [bucket, objectName] * @return: java.lang.String * @Author: MrFugui * @Date: 2021/11/15 */ 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进行下载,即使其所在的存储桶是私有的。 * * @Param: [bucketName, objectName, expires] * @return: java.lang.String * @Author: MrFugui * @Date: 2021/11/15 */ 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中所有的文件 * * @Param: [] * @return: java.util.List * @Author: MrFugui * @Date: 2021/11/15 */ public List listAllFile() throws Exception { List list = this.listBuckets(); List fileinfos = new ArrayList<>(); for (String bucketName : list) { fileinfos.addAll(this.listFiles(bucketName)); } return fileinfos; } } ``` 这里集成了minio sdk中的api [这是minio的api文档](https://docs.min.io/docs/java-client-api-reference.html#) ## 第四步,编写controller类 ```java package com.wangfugui.apprentice.controller; import com.wangfugui.apprentice.common.util.MinioUtil; import com.wangfugui.apprentice.common.util.ResponseUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.net.URLEncoder; @Api(tags = "文件操作接口") @RestController @RequestMapping(value = "/file") public class FileController { @Autowired MinioUtil minioUtil; @ApiOperation("上传一个文件") @RequestMapping(value = "/uploadfile", method = RequestMethod.POST) public ResponseUtils fileupload(@RequestParam MultipartFile uploadfile, @RequestParam String bucket, @RequestParam(required = false) String objectName) throws Exception { minioUtil.createBucket(bucket); if (objectName != null) { minioUtil.uploadFile(uploadfile.getInputStream(), bucket, objectName + "/" + uploadfile.getOriginalFilename()); } else { minioUtil.uploadFile(uploadfile.getInputStream(), bucket, uploadfile.getOriginalFilename()); } return ResponseUtils.success(); } @ApiOperation("列出所有的桶") @RequestMapping(value = "/listBuckets", method = RequestMethod.GET) public ResponseUtils listBuckets() throws Exception { return ResponseUtils.success(minioUtil.listBuckets()); } @ApiOperation("递归列出一个桶中的所有文件和目录") @RequestMapping(value = "/listFiles", method = RequestMethod.GET) public ResponseUtils listFiles(@RequestParam String bucket) throws Exception { return ResponseUtils.success(minioUtil.listFiles(bucket)); } @ApiOperation("下载一个文件") @RequestMapping(value = "/downloadFile", method = RequestMethod.GET) public void downloadFile(@RequestParam String bucket, @RequestParam String objectName, HttpServletResponse response) throws Exception { InputStream stream = minioUtil.download(bucket, objectName); ServletOutputStream output = response.getOutputStream(); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(objectName.substring(objectName.lastIndexOf("/") + 1), "UTF-8")); response.setContentType("application/octet-stream"); response.setCharacterEncoding("UTF-8"); IOUtils.copy(stream, output); } @ApiOperation("删除一个文件") @RequestMapping(value = "/deleteFile", method = RequestMethod.GET) public ResponseUtils deleteFile(@RequestParam String bucket, @RequestParam String objectName) throws Exception { minioUtil.deleteObject(bucket, objectName); return ResponseUtils.success(); } @ApiOperation("删除一个桶") @RequestMapping(value = "/deleteBucket", method = RequestMethod.GET) public ResponseUtils deleteBucket(@RequestParam String bucket) throws Exception { minioUtil.deleteBucket(bucket); return ResponseUtils.success(); } @ApiOperation("复制一个文件") @GetMapping("/copyObject") public ResponseUtils copyObject(@RequestParam String sourceBucket, @RequestParam String sourceObject, @RequestParam String targetBucket, @RequestParam String targetObject) throws Exception { minioUtil.copyObject(sourceBucket, sourceObject, targetBucket, targetObject); return ResponseUtils.success(); } @GetMapping("/getObjectInfo") @ApiOperation("获取文件信息") public ResponseUtils getObjectInfo(@RequestParam String bucket, @RequestParam String objectName) throws Exception { return ResponseUtils.success(minioUtil.getObjectInfo(bucket, objectName)); } @GetMapping("/getPresignedObjectUrl") @ApiOperation("获取一个连接以供下载") public ResponseUtils getPresignedObjectUrl(@RequestParam String bucket, @RequestParam String objectName, @RequestParam Integer expires) throws Exception { return ResponseUtils.success(minioUtil.getPresignedObjectUrl(bucket, objectName, expires)); } @GetMapping("/listAllFile") @ApiOperation("获取minio中所有的文件") public ResponseUtils listAllFile() throws Exception { return ResponseUtils.success(minioUtil.listAllFile()); } } ``` 注意这里的ResponseUtils请去往仓库中领取,仓库地址: [SpringBoot+MinIO](https://gitee.com/WangFuGui-Ma/spring-boot-minio) **妈耶,完了在yml中配置minio的地址,你没发现吧,叫你上课不认真听** ## 第五步,配置yml文件 ```yaml minio: url: http://1localhost:9000 #对象存储服务的URL accessKey: root #账户 secretKey: 123456 #密码 ``` 这步咋来的?请看我的[Linux安装MinIO](https://blog.csdn.net/csdnerM/article/details/121336618) ## 第六步,启动项目,访问api ![在这里插入图片描述](READMEimg/15689720ab8742d3ba7146933b3f5a08.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5o6J5aS05Y-R55qE546L5a-M6LS1,size_20,color_FFFFFF,t_70,g_se,x_16) 就ok啦!! 到这里就完成了springboot集成minio实现文件的上传等功能 ![在这里插入图片描述](READMEimg/23eefccf438f4aaeb5a143f1db1f0fa7.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAY3NkbmVyTQ==,size_16,color_FFFFFF,t_70,g_se,x_16)