当前位置:   article > 正文

springboot 对接 minio 分布式文件系统_springboot minio

springboot minio

1. minio介绍

Minio 是一个基于Go语言的对象存储服务。它实现了大部分亚马逊S3云存储服务接口,可以看做是是S3的开源版本,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。区别于分布式存储系统,minio的特色在于简单、轻量级,对开发者友好,认为存储应该是一个开发问题而不是一个运维问题。


2. minio下载地址

下载

3. liunx minio文件授权

chomd +x minio

4. 编写启动minio shell文件

vi run.sh

  1. #!/bin/bash
  2. #web管理界面登录用户
  3. export MINIO_ROOT_USER=minio
  4. #web管理界面登录密码
  5. export MINIO_ROOT_PASSWORD=minio
  6. #生成共享链接时,需要配置,否则是本地地址127.0.0.1,有地址的可以修改为自己地址
  7. export MINIO_SERVER_URL=http://IP:9002
  8. # nohup启动服务 指定文件存放路径 /root/data 还有设置日志文件路径 /root/minio/log
  9. nohup ./minio server --address :9002 --console-address :9001 /root/data/minio > /root/logs/minio.log 2>&1 &

5. 赋权限给予shell文件run.sh文件

 chmod u+x run.sh

.

6. 启动minio服务,执行sh文件

bash run.sh

7. 查看日志,我们在4的时候最后一条上有配置log地址

tail -f /root/logs/minio.log

8. 浏览器访问minio界面,并且输入在第四步配置的账号密码

9. 接下来我们可以创建一个我们作为测试的文件桶

 

 10. 当我们创建好桶之后,我们可以前往查看是否存在

11. 点击桶进入,手动测试上传文件

12. 上传文件之后我们可以选择某一个文件进行下载或者链接共享,链接共享默认时间为7天

13. 当我们点击共享时,会出现一个共享链接,我们可以直接在浏览器内查看相对应的文件

14. springboot 对接minio,加入POM文件

  1. <dependency>
  2. <groupId>io.minio</groupId>
  3. <artifactId>minio</artifactId>
  4. <version>7.1.0</version>
  5. </dependency>

15. 配置application文件

生成请求账号密码

  1. minio:
  2. endpoint: http://IP:9002
  3. accessKey: bjdZxvMDxAzYETgYn0aY 配置账号
  4. secretKey: uk7srkLHsYkwzvTYVzDBtwzlXz5fxsoMmNpbb3SN 配置密码
  5. bucketName: test 桶名称-默认

16.springboot 工具类

  1. package com.project.google.util;
  2. /**
  3. * @Description: TODO
  4. * @Author xgp
  5. * @Date 2023/8/7 8:05
  6. * @PackageName:com.project.google.util
  7. * @ClassName: MinioTemplate
  8. * @Version 1.0
  9. */
  10. import io.minio.*;
  11. import io.minio.messages.Bucket;
  12. import io.minio.messages.Item;
  13. import lombok.SneakyThrows;
  14. import org.apache.commons.io.IOUtils;
  15. import org.springframework.beans.factory.InitializingBean;
  16. import org.springframework.beans.factory.annotation.Value;
  17. import org.springframework.context.annotation.Configuration;
  18. import org.springframework.util.Assert;
  19. import org.springframework.web.multipart.MultipartFile;
  20. import javax.annotation.Resource;
  21. import javax.servlet.http.HttpServletResponse;
  22. import java.io.InputStream;
  23. import java.net.URLEncoder;
  24. import java.util.ArrayList;
  25. import java.util.Iterator;
  26. import java.util.List;
  27. import java.util.Optional;
  28. import java.util.stream.Collectors;
  29. /**
  30. * Minio 基础操作类
  31. *
  32. * @author: zhanghuaiyu
  33. * @since 2021-01-22 16:27
  34. */
  35. @Configuration
  36. public class MinioTemplate implements InitializingBean {
  37. private MinioClient minioClient;
  38. @Value("${minio.endpoint}")
  39. private String url;
  40. @Value("${minio.accessKey}")
  41. private String accessKey;
  42. @Value("${minio.secretKey}")
  43. private String secretKey;
  44. @Override
  45. public void afterPropertiesSet() {
  46. Assert.hasText(url, "Minio url 为空");
  47. Assert.hasText(accessKey, "Minio accessKey为空");
  48. Assert.hasText(secretKey, "Minio secretKey为空");
  49. this.minioClient = new MinioClient(url, accessKey, secretKey);
  50. }
  51. /**
  52. * 创建bucket
  53. * setBucketPolicy 设置权限才可以预览
  54. *
  55. * @param bucketName bucket名称
  56. */
  57. @SneakyThrows
  58. public Boolean createBucket(String bucketName) {
  59. if (!bucketExists(bucketName)) {
  60. minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
  61. StringBuilder builder = new StringBuilder();
  62. builder.append("{\n");
  63. builder.append(" \"Statement\": [\n");
  64. builder.append(" {\n");
  65. builder.append(" \"Action\": [\n");
  66. builder.append(" \"s3:GetBucketLocation\",\n");
  67. builder.append(" \"s3:ListBucket\"\n");
  68. builder.append(" ],\n");
  69. builder.append(" \"Effect\": \"Allow\",\n");
  70. builder.append(" \"Principal\": \"*\",\n");
  71. builder.append(" \"Resource\": \"arn:aws:s3:::bucketname\"\n");
  72. builder.append(" },\n");
  73. builder.append(" {\n");
  74. builder.append(" \"Action\": \"s3:GetObject\",\n");
  75. builder.append(" \"Effect\": \"Allow\",\n");
  76. builder.append(" \"Principal\": \"*\",\n");
  77. builder.append(" \"Resource\": \"arn:aws:s3:::my-bucketname/*.*\"\n");
  78. builder.append(" }\n");
  79. builder.append(" ],\n");
  80. builder.append(" \"Version\": \"2012-10-17\"\n");
  81. builder.append("}\n");
  82. minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucketName).config(builder.toString().replace("bucketname", bucketName)).build());
  83. return true;
  84. } else {
  85. return false;
  86. }
  87. }
  88. /**
  89. * 获取全部bucket
  90. * <p>
  91. * https://docs.minio.io/cn/java-client-api-reference.html#listBuckets
  92. */
  93. @SneakyThrows
  94. public List<Bucket> getAllBuckets() {
  95. return minioClient.listBuckets();
  96. }
  97. /**
  98. * 根据bucketName获取信息
  99. *
  100. * @param bucketName bucket名称
  101. */
  102. @SneakyThrows
  103. public Optional<Bucket> getBucket(String bucketName) {
  104. return minioClient.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
  105. }
  106. /**
  107. * 根据bucketName删除信息
  108. *
  109. * @param bucketName bucket名称
  110. */
  111. @SneakyThrows
  112. public void removeBucket(String bucketName) {
  113. minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
  114. }
  115. /**
  116. * 根据文件前置查询文件
  117. *
  118. * @param bucketName bucket名称
  119. * @param prefix 前缀
  120. * @param recursive 是否递归查询
  121. * @return MinioItem 列表
  122. */
  123. @SneakyThrows
  124. public List getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) {
  125. List<Item> list = new ArrayList<>();
  126. Iterable<Result<Item>> objectsIterator = minioClient.listObjects(bucketName, prefix, recursive);
  127. if (objectsIterator != null) {
  128. Iterator<Result<Item>> iterator = objectsIterator.iterator();
  129. if (iterator != null) {
  130. while (iterator.hasNext()) {
  131. Result<Item> result = iterator.next();
  132. Item item = result.get();
  133. list.add(item);
  134. }
  135. }
  136. }
  137. return list;
  138. }
  139. /**
  140. * 获取文件外链
  141. *
  142. * @param bucketName bucket名称
  143. * @param objectName 文件名称
  144. * @param expires 过期时间 <=7
  145. * @return url
  146. */
  147. @SneakyThrows
  148. public String getObjectUrl(String bucketName, String objectName, Integer expires) {
  149. return minioClient.presignedGetObject(bucketName, objectName, expires);
  150. }
  151. /**
  152. * 获取文件路径
  153. *
  154. * @param bucketName
  155. * @param fileName
  156. * @return
  157. */
  158. @SneakyThrows
  159. public String getObjectUrl(String bucketName, String fileName) {
  160. return minioClient.getObjectUrl(bucketName, fileName);
  161. }
  162. /**
  163. * 获取文件
  164. *
  165. * @param bucketName bucket名称
  166. * @param objectName 文件名称
  167. * @return 二进制流
  168. */
  169. @SneakyThrows
  170. public InputStream getObject(String bucketName, String objectName) {
  171. return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
  172. }
  173. /**
  174. * 获取文件
  175. *
  176. * @param bucketName
  177. * @param objectName
  178. * @return
  179. */
  180. @SneakyThrows
  181. public ObjectStat statObject(String bucketName, String objectName) {
  182. return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
  183. }
  184. /**
  185. * 上传文件
  186. *
  187. * @param bucketName bucket名称
  188. * @param objectName 文件名称
  189. * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject
  190. */
  191. public String putObject(String bucketName, String objectName, MultipartFile file) throws Exception {
  192. if (!this.bucketExists(bucketName)) {
  193. this.createBucket(bucketName);
  194. }
  195. minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(file.getInputStream(), file.getSize(), PutObjectArgs.MIN_MULTIPART_SIZE).contentType(file.getContentType()).build());
  196. return bucketName;
  197. }
  198. /**
  199. * 上传文件
  200. *
  201. * @param bucketName bucket名称
  202. * @param objectName 文件名称
  203. * @param stream 文件流
  204. * @param size 大小
  205. * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject
  206. */
  207. public void putObject(String bucketName, String objectName, InputStream stream, long size) throws Exception {
  208. minioClient.putObject(bucketName, objectName, stream, new PutObjectOptions(stream.available(), -1));
  209. }
  210. /**
  211. * 获取文件信息, 如果抛出异常则说明文件不存在
  212. *
  213. * @param bucketName bucket名称
  214. * @param objectName 文件名称
  215. * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#statObject
  216. */
  217. public ObjectStat getObjectInfo(String bucketName, String objectName) throws Exception {
  218. return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
  219. }
  220. /**
  221. * 删除文件
  222. *
  223. * @param bucketName bucket名称
  224. * @param objectName 文件名称
  225. * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#removeObject
  226. */
  227. public void removeObject(String bucketName, String objectName) throws Exception {
  228. minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
  229. }
  230. /**
  231. * 批量删除文件夹内所有文件
  232. *
  233. * @param bucketName bucket名称
  234. * @param objectName 文件名称
  235. * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#removeObject
  236. */
  237. public void removeObjects(String bucketName, String objectName) throws Exception {
  238. List<Item> list = getAllObjectsByPrefix(bucketName, objectName, false);
  239. for (Item item : list) {
  240. removeObject(bucketName, item.objectName());
  241. }
  242. }
  243. @SneakyThrows
  244. public boolean bucketExists(String bucketName) {
  245. return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
  246. }
  247. /**
  248. * 文件下载
  249. *
  250. * @param response
  251. * @param bucket
  252. * @param objectName
  253. * @param outName
  254. * @throws Exception
  255. */
  256. public void download(HttpServletResponse response, String bucket, String objectName, String outName) throws Exception {
  257. ObjectStat stat = this.statObject(bucket, objectName);
  258. response.setContentType(stat.contentType());
  259. response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(outName, "UTF-8"));
  260. response.setHeader("FileName", URLEncoder.encode(outName, "UTF-8"));
  261. InputStream in = this.getObject(bucket, objectName);
  262. IOUtils.copy(in, response.getOutputStream());
  263. in.close();
  264. }
  265. /**
  266. * 合并分片文件到指定目录
  267. *
  268. * @param bucket
  269. * @param fileName
  270. * @param sources
  271. * @return
  272. * @throws Exception
  273. */
  274. public ObjectWriteResponse composeObject(String bucket, String fileName, List<ComposeSource> sources) throws Exception {
  275. ObjectWriteResponse response = minioClient.composeObject(ComposeObjectArgs.builder()
  276. .bucket(bucket)
  277. .object(fileName)
  278. .sources(sources)
  279. .build());
  280. return response;
  281. }
  282. }

 17.请求测试controller方法

  1. package com.project.google.controller;
  2. import afu.org.checkerframework.checker.oigj.qual.O;
  3. import com.project.google.util.MinioTemplate;
  4. import io.minio.messages.Bucket;
  5. import org.apache.commons.io.IOUtils;
  6. import org.checkerframework.checker.units.qual.A;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.http.MediaType;
  9. import org.springframework.web.bind.annotation.GetMapping;
  10. import org.springframework.web.bind.annotation.PostMapping;
  11. import org.springframework.web.bind.annotation.RequestParam;
  12. import org.springframework.web.bind.annotation.RestController;
  13. import org.springframework.web.multipart.MultipartFile;
  14. import java.io.IOException;
  15. import java.io.InputStream;
  16. import java.util.*;
  17. /**
  18. * @Description: TODO
  19. * @Author xgp
  20. * @Date 2023/8/7 8:35
  21. * @PackageName:com.project.google.controller
  22. * @ClassName: TbMinioController
  23. * @Version 1.0
  24. */
  25. @RestController
  26. public class TbMinioController {
  27. @Autowired
  28. private MinioTemplate minioTemplate;
  29. //创建新的桶
  30. @GetMapping("createBucket")
  31. public Object createBucket(String bucketName){
  32. return minioTemplate.createBucket(bucketName);
  33. }
  34. //获取对应桶信息
  35. @GetMapping("getList")
  36. public Object getList(String bucketName){
  37. Bucket bucket = minioTemplate.getBucket(bucketName).get();
  38. Map<String,Object> map = new HashMap<>();
  39. map.put("name",bucket.name());
  40. map.put("createDate",bucket.creationDate());
  41. return map;
  42. }
  43. //获取所有桶信息
  44. @GetMapping("getAll")
  45. public Object getAll(){
  46. List<Map> list = new ArrayList<>();
  47. List<Bucket> buckets = minioTemplate.getAllBuckets();
  48. buckets.stream().forEach(item -> {
  49. Map<String,Object> map = new HashMap<>();
  50. map.put("name",item.name());
  51. map.put("createDate",item.creationDate());
  52. list.add(map);
  53. });
  54. return list;
  55. }
  56. /**上传文件到对应桶里,如果你想放入指定文件夹,传入文件名前面带上文件夹名称及路径,比如 test文件夹就- test/文件名,依次类推*/
  57. @PostMapping("uploadFile")
  58. public Object uploadFile(@RequestParam("file") MultipartFile file) throws Exception {
  59. /**文件夹属性,可加载文件前方*/
  60. return minioTemplate.putObject("test","uu/" + file.getOriginalFilename(),file);
  61. }
  62. /**获取图片信息,二进制数据转换为图片呈现*/
  63. @GetMapping(value = "getFile", produces = MediaType.IMAGE_JPEG_VALUE)
  64. public byte[] getFile(@RequestParam("bucketName") String bucketName
  65. ,@RequestParam("objectName") String objectName) throws IOException {
  66. InputStream stream = minioTemplate.getObject(bucketName, objectName);
  67. byte[] bytes = IOUtils.toByteArray(stream);
  68. return bytes;
  69. }
  70. /**获取图片分享链接,expires为过期时间,可为小于等于7*/
  71. @GetMapping(value = "getObjectUrl")
  72. public String getObjectUrl(@RequestParam("bucketName") String bucketName
  73. ,@RequestParam("objectName") String objectName) throws IOException {
  74. return minioTemplate.getObjectUrl(bucketName, objectName, 1);
  75. }
  76. }

18.接口测试

18.1 查询test bucket信息

 

18.2 获取所有bucket信息

18.3 上传文件,我这边是通过apipox进行测试

18.4 查看图片信息

18.5 生成共享链接

到此,整个对接过程就已经差不多了,其他扩展功能,如有需要,可以咨询这边,给出解答或者思路。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/554376
推荐阅读
相关标签
  

闽ICP备14008679号