• SpringBoot 整合 Minio 实现 文件上传


    一、搭建

    1.1、Docker 下 MinIO 安装与配置

    Docker 下 MinIO 安装与配置_JAVA·D·WangJing的博客-CSDN博客

    1.2、创建存储桶

    1.3、创建服务账号

    二、创建 springboot 项目

    mac idea 创建 springboot 项目_JAVA·D·WangJing的博客-CSDN博客_mac搭建一个springboot项目

    三、pom.xml依赖配置

    1. <dependency>
    2. <groupId>io.miniogroupId>
    3. <artifactId>minioartifactId>
    4. <version>8.0.3version>
    5. dependency>

    四、bootstrap.yml 或 application.yml 添加配置

    1. spring:
    2. # 配置文件上传大小限制
    3. servlet:
    4. multipart:
    5. max-file-size: 200GB
    6. max-request-size: 200GB
    7. minio:
    8. endpoint: http://**.**.**.**:8801
    9. accessKey: bx20******k84h
    10. secretKey: 4wL8****************1mok
    11. bucketName: test

    五、代码

    5.1、MinIoClientConfig 类(注册minio客户端)

    1. package com.wangjing.minio.conf;
    2. import io.minio.MinioClient;
    3. import lombok.Data;
    4. import org.springframework.beans.factory.annotation.Value;
    5. import org.springframework.context.annotation.Bean;
    6. import org.springframework.stereotype.Component;
    7. /**
    8. * @author: wangjing
    9. * @createTime: 2022-09-09 14:31
    10. * @version:
    11. * @Description: 注册minio客户端
    12. */
    13. @Data
    14. @Component
    15. public class MinIoClientConfig {
    16. @Value("${minio.endpoint}")
    17. private String endpoint;
    18. @Value("${minio.accessKey}")
    19. private String accessKey;
    20. @Value("${minio.secretKey}")
    21. private String secretKey;
    22. /**
    23. * 注入minio 客户端
    24. *
    25. * @return
    26. */
    27. @Bean
    28. public MinioClient minioClient() {
    29. return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
    30. }
    31. }

    5.2、MinioService 类(minio工具类)

    1. package com.wangjing.minio.service;
    2. import com.wangjing.minio.entity.ObjectItem;
    3. import io.minio.*;
    4. import io.minio.messages.DeleteError;
    5. import io.minio.messages.DeleteObject;
    6. import io.minio.messages.Item;
    7. import org.apache.commons.io.IOUtils;
    8. import org.springframework.beans.factory.annotation.Autowired;
    9. import org.springframework.beans.factory.annotation.Value;
    10. import org.springframework.http.HttpHeaders;
    11. import org.springframework.http.HttpStatus;
    12. import org.springframework.http.MediaType;
    13. import org.springframework.http.ResponseEntity;
    14. import org.springframework.stereotype.Component;
    15. import org.springframework.web.multipart.MultipartFile;
    16. import java.io.ByteArrayOutputStream;
    17. import java.io.IOException;
    18. import java.io.InputStream;
    19. import java.io.UnsupportedEncodingException;
    20. import java.net.URLEncoder;
    21. import java.util.ArrayList;
    22. import java.util.Arrays;
    23. import java.util.List;
    24. import java.util.stream.Collectors;
    25. /**
    26. * @author: wangjing
    27. * @createTime: 2022-09-09 14:33
    28. * @version:
    29. * @Description: minio工具类
    30. */
    31. @Component
    32. public class MinioService {
    33. @Autowired
    34. private MinioClient minioClient;
    35. @Value("${minio.bucketName}")
    36. private String bucketName;
    37. /**
    38. * 判断bucket是否存在,不存在则创建
    39. *
    40. * @param name
    41. */
    42. public void existBucket(String name) {
    43. try {
    44. boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());
    45. if (!exists) {
    46. minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build());
    47. }
    48. } catch (Exception e) {
    49. e.printStackTrace();
    50. }
    51. }
    52. /**
    53. * 创建存储bucket
    54. *
    55. * @param bucketName
    56. * @return
    57. */
    58. public Boolean makeBucket(String bucketName) {
    59. try {
    60. minioClient.makeBucket(MakeBucketArgs.builder()
    61. .bucket(bucketName)
    62. .build());
    63. } catch (Exception e) {
    64. e.printStackTrace();
    65. return false;
    66. }
    67. return true;
    68. }
    69. /**
    70. * 删除存储bucket
    71. *
    72. * @param bucketName
    73. * @return
    74. */
    75. public Boolean removeBucket(String bucketName) {
    76. try {
    77. minioClient.removeBucket(RemoveBucketArgs.builder()
    78. .bucket(bucketName)
    79. .build());
    80. } catch (Exception e) {
    81. e.printStackTrace();
    82. return false;
    83. }
    84. return true;
    85. }
    86. /**
    87. * 多文件上传
    88. *
    89. * @param multipartFileArr
    90. * @return
    91. */
    92. public List upload(MultipartFile[] multipartFileArr) {
    93. List names = new ArrayList<>(multipartFileArr.length);
    94. for (MultipartFile file : multipartFileArr) {
    95. names.add(upload(file));
    96. }
    97. return names;
    98. }
    99. /**
    100. * 单文件上传
    101. *
    102. * @param multipartFile
    103. * @return
    104. */
    105. public String upload(MultipartFile multipartFile) {
    106. String fileName = multipartFile.getOriginalFilename();
    107. String[] split = fileName.split("\\.");
    108. if (split.length > 1) {
    109. fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1];
    110. } else {
    111. fileName = fileName + System.currentTimeMillis();
    112. }
    113. InputStream in = null;
    114. try {
    115. in = multipartFile.getInputStream();
    116. minioClient.putObject(PutObjectArgs.builder()
    117. .bucket(bucketName)
    118. .object(fileName)
    119. .stream(in, in.available(), -1)
    120. .contentType(multipartFile.getContentType())
    121. .build()
    122. );
    123. } catch (Exception e) {
    124. e.printStackTrace();
    125. } finally {
    126. if (in != null) {
    127. try {
    128. in.close();
    129. } catch (IOException e) {
    130. e.printStackTrace();
    131. }
    132. }
    133. }
    134. return fileName;
    135. }
    136. /**
    137. * 下载文件
    138. *
    139. * @param fileName
    140. * @return
    141. */
    142. public ResponseEntity<byte[]> download(String fileName) {
    143. ResponseEntity<byte[]> responseEntity = null;
    144. InputStream in = null;
    145. ByteArrayOutputStream out = null;
    146. try {
    147. in = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
    148. out = new ByteArrayOutputStream();
    149. IOUtils.copy(in, out);
    150. //封装返回值
    151. byte[] bytes = out.toByteArray();
    152. HttpHeaders headers = new HttpHeaders();
    153. try {
    154. headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
    155. } catch (UnsupportedEncodingException e) {
    156. e.printStackTrace();
    157. }
    158. headers.setContentLength(bytes.length);
    159. headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    160. headers.setAccessControlExposeHeaders(Arrays.asList("*"));
    161. responseEntity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
    162. } catch (Exception e) {
    163. e.printStackTrace();
    164. } finally {
    165. try {
    166. if (in != null) {
    167. try {
    168. in.close();
    169. } catch (IOException e) {
    170. e.printStackTrace();
    171. }
    172. }
    173. if (out != null) {
    174. out.close();
    175. }
    176. } catch (IOException e) {
    177. e.printStackTrace();
    178. }
    179. }
    180. return responseEntity;
    181. }
    182. /**
    183. * 查看文件对象
    184. *
    185. * @param bucketName
    186. * @return
    187. */
    188. public List listObjects(String bucketName) {
    189. Iterable> results = minioClient.listObjects(
    190. ListObjectsArgs.builder().bucket(bucketName).build());
    191. List objectItems = new ArrayList<>();
    192. try {
    193. for (Result result : results) {
    194. Item item = result.get();
    195. ObjectItem objectItem = new ObjectItem();
    196. objectItem.setObjectName(item.objectName());
    197. objectItem.setSize(item.size());
    198. objectItems.add(objectItem);
    199. }
    200. } catch (Exception e) {
    201. e.printStackTrace();
    202. return null;
    203. }
    204. return objectItems;
    205. }
    206. /**
    207. * 批量删除文件对象
    208. *
    209. * @param bucketName
    210. * @param objects
    211. * @return
    212. */
    213. public Iterable> removeObjects(String bucketName, List objects) {
    214. List dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());
    215. Iterable> results =
    216. minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());
    217. return results;
    218. }
    219. }

    5.3、ObjectItem 类(实体类)

    1. package com.wangjing.minio.entity;
    2. import lombok.Data;
    3. /**
    4. * @author: wangjing
    5. * @createTime: 2022-09-09 14:36
    6. * @version:
    7. * @Description: 实体类
    8. */
    9. @Data
    10. public class ObjectItem {
    11. private String objectName;
    12. private Long size;
    13. }

    5.4、MinioController 类(测试接口类)

    1. package com.wangjing.minio.controller;
    2. import com.wangjing.minio.service.MinioService;
    3. import lombok.extern.slf4j.Slf4j;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.beans.factory.annotation.Value;
    6. import org.springframework.web.bind.annotation.PostMapping;
    7. import org.springframework.web.bind.annotation.RestController;
    8. import org.springframework.web.multipart.MultipartFile;
    9. import java.util.List;
    10. /**
    11. * @author:
    12. * @createTime: 2022-09-09 14:37
    13. * @version:
    14. * @Description:
    15. */
    16. @RestController
    17. @Slf4j
    18. public class MinioController {
    19. @Autowired
    20. private MinioService minioService;
    21. @Value("${minio.endpoint}")
    22. private String address;
    23. @Value("${minio.bucketName}")
    24. private String bucketName;
    25. @PostMapping("/upload")
    26. public Object upload(MultipartFile file) {
    27. String upload = minioUtil.upload(file);
    28. return address + "/" + bucketName + "/" + upload;
    29. }
    30. }

    六、测试

    6.1、postMan 请求接口

    6.2、返回url 通过浏览器打开

    发现权限有问题,更改桶的展示权限

    再次刷新,可以正常访问

    6.3、登录minio 后台管理,查看test 桶数据

    注:以上内容仅提供参考和交流,请勿用于商业用途,如有侵权联系本人删除!

  • 相关阅读:
    [React] react-hooks如何使用
    【Vue组件化编程】
    小知识:使用oracle用户查看RAC集群资源状态
    我的创作纪念日
    网络协议:TCP/IP协议
    【TB作品】MSP430G2533,读取dht11,显示到lcd1602显示屏,串口发送到电脑
    身份和访问管理IAM能力之RADIUS认证
    mac新环境
    图片Base64编码解码的优缺点及应用场景分析
    喜马拉雅后端一面
  • 原文地址:https://blog.csdn.net/wang_jing_jing/article/details/126784120