日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

SpringBoot笔记:SpringBoot集成MinIO分布式文件系统

發布時間:2025/3/19 windows 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringBoot笔记:SpringBoot集成MinIO分布式文件系统 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 搭建MinIO集群
  • SpringBoot集成
    • 添加依賴
    • 添加配置
    • 獲取MinioClient
    • MinioUtils完整工具類
    • 測試代碼

搭建MinIO集群

首先搭建MinIO的分布式集群,集群搭建參考《CentOS7安裝筆記:minio分布式集群搭建》

SpringBoot集成

添加依賴

首先,添加如下依賴

<!-- Springoot集成Minio工具--><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>7.1.0</version></dependency>

添加配置

在yml中添加如下配置:

# minio 連接參數 minio:# URL,域名,或者ip地址endpoint: minio-1# 端口號port: 9000# 用戶名accessKey: myminio# 密碼secretKey: Leo825Test# 默認的存儲桶bucketName: testbucket

獲取MinioClient

@Value("${minio.endpoint}")private String endpoint;@Value("${minio.port}")private Integer port;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;@Value("${minio.bucketName}")private String bucketName;/*** 定義一個單例的MinioClient對象*/private static MinioClient minioClient;public MinioClient getInstance() {if (minioClient == null) {minioClient = MinioClient.builder().endpoint(endpoint, port, false).credentials(accessKey, secretKey).build();}return minioClient;}

以上就是核心代碼實現了,具體是怎么實現可以根據個人喜好。

MinioUtils完整工具類

package com.demo.util;import io.minio.*; import io.minio.errors.ErrorResponseException; import io.minio.errors.InvalidExpiresRangeException; import io.minio.messages.Bucket; import io.minio.messages.DeleteError; import io.minio.messages.Item; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.nio.charset.StandardCharsets; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List;/*** springboot集成MinIO工具類*/ @Slf4j @Component public class MinioUtils {@Value("${minio.endpoint}")private String endpoint;@Value("${minio.port}")private Integer port;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;@Value("${minio.bucketName}")private String bucketName;/*** 定義一個單例的MinioClient對象*/private static MinioClient minioClient;/*** 默認超時時間*/private static final int DEFAULT_EXPIRY_TIME = 7 * 24 * 3600;public MinioClient getInstance() {if (minioClient == null) {minioClient = MinioClient.builder().endpoint(endpoint, port, false).credentials(accessKey, secretKey).build();}return minioClient;}/*** 檢查存儲桶是否存在** @param bucketName 存儲桶名稱* @return*/@SneakyThrowspublic boolean bucketExists(String bucketName) {boolean flag = minioClient.bucketExists(bucketName);if (flag) {return true;}return false;}/*** 創建存儲桶** @param bucketName 存儲桶名稱*/@SneakyThrowspublic boolean makeBucket(String bucketName) {boolean flag = bucketExists(bucketName);if (!flag) {minioClient.makeBucket(bucketName);return true;} else {return false;}}/*** 列出所有存儲桶名稱** @return*/@SneakyThrowspublic List<String> listBucketNames() {List<Bucket> bucketList = listBuckets();List<String> bucketListName = new ArrayList<>();for (Bucket bucket : bucketList) {bucketListName.add(bucket.name());}return bucketListName;}/*** 列出所有存儲桶** @return*/@SneakyThrowspublic List<Bucket> listBuckets() {return minioClient.listBuckets();}/*** 刪除存儲桶** @param bucketName 存儲桶名稱* @return*/@SneakyThrowspublic boolean removeBucket(String bucketName) {boolean flag = bucketExists(bucketName);if (flag) {Iterable<Result<Item>> myObjects = listObjects(bucketName);for (Result<Item> result : myObjects) {Item item = result.get();// 有對象文件,則刪除失敗if (item.size() > 0) {return false;}}// 刪除存儲桶,注意,只有存儲桶為空時才能刪除成功。minioClient.removeBucket(bucketName);flag = bucketExists(bucketName);if (!flag) {return true;}}return false;}/*** 列出存儲桶中的所有對象名稱** @param bucketName 存儲桶名稱* @return*/@SneakyThrowspublic List<String> listObjectNames(String bucketName) {List<String> listObjectNames = new ArrayList<>();boolean flag = bucketExists(bucketName);if (flag) {Iterable<Result<Item>> myObjects = listObjects(bucketName);for (Result<Item> result : myObjects) {Item item = result.get();listObjectNames.add(item.objectName());}}return listObjectNames;}/*** 列出存儲桶中的所有對象** @param bucketName 存儲桶名稱* @return*/@SneakyThrowspublic Iterable<Result<Item>> listObjects(String bucketName) {boolean flag = bucketExists(bucketName);if (flag) {return minioClient.listObjects(bucketName);}return null;}/*** 通過文件上傳到對象** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱* @param fileName File name* @return*/@SneakyThrowspublic boolean putObject(String bucketName, String objectName, String fileName) {boolean flag = bucketExists(bucketName);if (flag) {minioClient.putObject(bucketName, objectName, fileName, null);ObjectStat statObject = statObject(bucketName, objectName);if (statObject != null && statObject.length() > 0) {return true;}}return false;}/*** MultipartFile格式文件上傳** @param bucketName* @param multipartFile*/@SneakyThrowspublic void putObject(String bucketName, MultipartFile multipartFile, String filename) {PutObjectOptions putObjectOptions = new PutObjectOptions(multipartFile.getSize(), PutObjectOptions.MIN_MULTIPART_SIZE);putObjectOptions.setContentType(multipartFile.getContentType());minioClient.putObject(bucketName, filename, multipartFile.getInputStream(), putObjectOptions);}/*** 通過InputStream上傳對象** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱* @param stream 要上傳的流* @param stream 要上傳的文件類型 MimeTypeUtils.IMAGE_JPEG_VALUE* @return*/@SneakyThrowspublic boolean putObject(String bucketName, String objectName, InputStream stream, String contentType) {boolean flag = bucketExists(bucketName);if (flag) {PutObjectOptions putObjectOptions = new PutObjectOptions(stream.available(), -1);/*** 開啟公共類功能設置setContentType*/if (!StringUtils.isEmpty(contentType)) {putObjectOptions.setContentType(contentType);}minioClient.putObject(bucketName, objectName, stream, putObjectOptions);ObjectStat statObject = statObject(bucketName, objectName);if (statObject != null && statObject.length() > 0) {return true;}}return false;}/*** 以流的形式獲取一個文件對象** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱* @return*/@SneakyThrowspublic InputStream getObject(String bucketName, String objectName) {boolean flag = bucketExists(bucketName);if (flag) {ObjectStat statObject = statObject(bucketName, objectName);if (statObject != null && statObject.length() > 0) {InputStream stream = minioClient.getObject(bucketName, objectName);return stream;}}return null;}/*** 以流的形式獲取一個文件對象(斷點下載)** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱* @param offset 起始字節的位置* @param length 要讀取的長度 (可選,如果無值則代表讀到文件結尾)* @return*/@SneakyThrowspublic InputStream getObject(String bucketName, String objectName, long offset, Long length) {boolean flag = bucketExists(bucketName);if (flag) {ObjectStat statObject = statObject(bucketName, objectName);if (statObject != null && statObject.length() > 0) {InputStream stream = minioClient.getObject(bucketName, objectName, offset, length);return stream;}}return null;}/*** 下載并將文件保存到本地** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱* @param fileName File name* @return*/@SneakyThrowspublic boolean getObject(String bucketName, String objectName, String fileName) {boolean flag = bucketExists(bucketName);if (flag) {ObjectStat statObject = statObject(bucketName, objectName);if (statObject != null && statObject.length() > 0) {minioClient.getObject(bucketName, objectName, fileName);return true;}}return false;}/*** 刪除一個對象** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱*/@SneakyThrowspublic boolean removeObject(String bucketName, String objectName) {boolean flag = bucketExists(bucketName);if (flag) {minioClient.removeObject(bucketName, objectName);return true;}return false;}/*** 刪除指定桶的多個文件對象,返回刪除錯誤的對象列表,全部刪除成功,返回空列表** @param bucketName 存儲桶名稱* @param objectNames 含有要刪除的多個object名稱的迭代器對象* @return*/@SneakyThrowspublic List<String> removeObject(String bucketName, List<String> objectNames) {List<String> deleteErrorNames = new ArrayList<>();boolean flag = bucketExists(bucketName);if (flag) {Iterable<Result<DeleteError>> results = minioClient.removeObjects(bucketName, objectNames);for (Result<DeleteError> result : results) {DeleteError error = result.get();deleteErrorNames.add(error.objectName());}}return deleteErrorNames;}/*** 生成一個給HTTP GET請求用的presigned URL。* 瀏覽器/移動端的客戶端可以用這個URL進行下載,即使其所在的存儲桶是私有的。這個presigned URL可以設置一個失效時間,默認值是7天。** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱* @param expires 失效時間(以秒為單位),默認是7天,不得大于七天* @return*/@SneakyThrowspublic String presignedGetObject(String bucketName, String objectName, Integer expires) {boolean flag = bucketExists(bucketName);String url = "";if (flag) {if (expires < 1 || expires > DEFAULT_EXPIRY_TIME) {throw new InvalidExpiresRangeException(expires,"expires must be in range of 1 to " + DEFAULT_EXPIRY_TIME);}url = minioClient.presignedGetObject(bucketName, objectName, expires);}return url;}/*** 生成一個給HTTP PUT請求用的presigned URL。* 瀏覽器/移動端的客戶端可以用這個URL進行上傳,即使其所在的存儲桶是私有的。這個presigned URL可以設置一個失效時間,默認值是7天。** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱* @param expires 失效時間(以秒為單位),默認是7天,不得大于七天* @return*/@SneakyThrowspublic String presignedPutObject(String bucketName, String objectName, Integer expires) {boolean flag = bucketExists(bucketName);String url = "";if (flag) {if (expires < 1 || expires > DEFAULT_EXPIRY_TIME) {throw new InvalidExpiresRangeException(expires,"expires must be in range of 1 to " + DEFAULT_EXPIRY_TIME);}url = minioClient.presignedPutObject(bucketName, objectName, expires);}return url;}/*** 獲取對象的元數據** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱* @return*/@SneakyThrowspublic ObjectStat statObject(String bucketName, String objectName) {boolean flag = bucketExists(bucketName);if (flag) {ObjectStat statObject = minioClient.statObject(bucketName, objectName);return statObject;}return null;}/*** 文件訪問路徑** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱* @return*/@SneakyThrowspublic String getObjectUrl(String bucketName, String objectName) {boolean flag = bucketExists(bucketName);String url = "";if (flag) {url = minioClient.getObjectUrl(bucketName, objectName);}return url;}/*** web下載** @param bucketName 存儲桶名稱* @param fileName 文件名* @param originalName 原始文件名* @param response 輸出對象*/public void downloadFile(String bucketName, String fileName, String originalName, HttpServletResponse response) {try {InputStream file = minioClient.getObject(bucketName, fileName);String filename = new String(fileName.getBytes("ISO8859-1"), StandardCharsets.UTF_8);if (!StringUtils.isEmpty(originalName)) {filename = originalName;}response.setHeader("Content-Disposition", "attachment;filename=" + filename);ServletOutputStream servletOutputStream = response.getOutputStream();int len;byte[] buffer = new byte[1024];while ((len = file.read(buffer)) > 0) {servletOutputStream.write(buffer, 0, len);}servletOutputStream.flush();file.close();servletOutputStream.close();} catch (ErrorResponseException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}/*** @return java.util.List<io.minio.messages.Bucket>* @Description 獲取minio所有的桶**/@SneakyThrowspublic List<Bucket> getAllBucket() {// 獲取minio中所以的bucketList<Bucket> buckets = getInstance().listBuckets();for (Bucket bucket : buckets) {log.info("bucket 名稱: {} ,創建時間: {}", bucket.name(), DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(bucket.creationDate().withZoneSameInstant(ZoneId.of("Asia/Shanghai"))));}return buckets;}/*** @param inputStream: 輸入流* @param objectName: 存儲桶里的對象名稱* @return void* @Description 將圖片上傳到minio服務器**/@SneakyThrowspublic void uploadToMinio(InputStream inputStream, String objectName) {long start = System.currentTimeMillis();try {long size = inputStream.available();PutObjectArgs putObjectArgs = PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(inputStream, size, -1).build();// 上傳到miniogetInstance().putObject(putObjectArgs);} catch (Exception e) {log.error("上傳異常:", e);} finally {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {log.error("上傳文件關閉流異常", e);}}}long end = System.currentTimeMillis();log.info("上傳 {} 文件,總耗時為:{} ms", objectName, end - start);}/*** @param objectName: 存儲桶里的對象名稱* @return java.lang.String* @Description 根據指定的objectName獲取下載鏈接,需要bucket設置可下載的策略**/@SneakyThrowspublic String getUrlByObjectName(String objectName) {String objectUrl = null;try {objectUrl = getInstance().getObjectUrl(bucketName, objectName);} catch (Exception e) {log.error("獲取下載鏈接異常", e);}return objectUrl;}/*** @param objectName: 存儲桶里的對象名稱* @param fileName: 文件名稱* @param dir: 文件目錄* @return void* @Description 根據objectName從minio中下載文件到指定的目錄**/@SneakyThrowspublic void downloadFromMinioToFile(String objectName, String fileName, String dir) {long start = System.currentTimeMillis();GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName).object(objectName).build();File file = new File(dir);if (!file.exists()) {file.mkdirs();}//使用BufferedInputStream和BufferedOutputStream可以提高IO效率try (BufferedInputStream bis = new BufferedInputStream(getInstance().getObject(objectArgs));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(dir, fileName.substring(fileName.lastIndexOf("/") + 1))))) {int length;//讀取內容while ((length = bis.read()) != -1) {bos.write(length);bos.flush();//當讀取的緩沖區到了8192字節后刷出到輸出文件}} catch (Exception e) {log.error("下載異常", e);}long end = System.currentTimeMillis();log.info("下載 {} 文件,總耗時為:{} ms", objectName, end - start);} }

測試代碼

部分測試代碼如下所示:

package com.demo;import com.demo.util.MinioUtils; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream;@SpringBootTest @Slf4j class SpringbootMinioApplicationTests {@AutowiredMinioUtils minioUtils;@Testvoid contextLoads() {}@Testpublic void testGetAllBucket() {minioUtils.getAllBucket();}@Testpublic void testUploadToMinio() {String filePath = "D:\\SoftPackage\\apache-maven-3.6.3-bin.zip";try (InputStream inputStream = new FileInputStream(filePath)) {minioUtils.uploadToMinio(inputStream, "apache-maven");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}@Testpublic void testGetUrlByObjectName() {log.info(minioUtils.getUrlByObjectName("apache-maven"));}@Testpublic void testDownloadFromMinioToFile() {String objName = "apache-maven";String fileName = "test_apache-maven-3.6.3-bin.zip";String dir = "D:\\SoftPackage";minioUtils.downloadFromMinioToFile(objName, fileName, dir);} }

總結

以上是生活随笔為你收集整理的SpringBoot笔记:SpringBoot集成MinIO分布式文件系统的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。