在 Spring Boot 中集成 MinIO 對象存儲
MinIO 是一個開源的對象存儲服務(wù)器,專注于高性能、分布式和兼容S3 API的存儲解決方案。本文將介紹如何在 Spring Boot 應(yīng)用程序中集成 MinIO,以便您可以輕松地將對象存儲集成到您的應(yīng)用中。
安裝minio
1.拉取 minio Docker鏡像
docker pull minio/minio
2.創(chuàng)建minio數(shù)據(jù)和配置目錄
mkdir -p /data/minio/data /data/minio/config
3.運行minio容器,設(shè)置訪問和密鑰并掛載數(shù)據(jù)卷
docker run -p 9090:9090 -p 9000:9000 --name minio \ -v ~/data/minio/data:/data \ -v ~/data/minio/config:/root/.minio \ -e "MINIO_ACCESS_KEY=minio" \ -e "MINIO_SECRET_KEY=minio123" \ minio/minio server /data --console-address ":9090"
或者 使用 docker-compose.yml
version: '3.9' services: minio: command: 'server /data --console-address ":9090"' image: minio/minio environment: - MINIO_SECRET_KEY=minio123 - MINIO_ACCESS_KEY=minio volumes: - '~/data/minio/config:/root/.minio' - '~/data/minio/data:/data' container_name: minio ports: - '9000:9000' - '9090:9090'
mkdir``~/minio/data
在您的主目錄中創(chuàng)建一個新的本地目錄。
docker run
啟動 MinIO 容器。
-p
將本地端口綁定到容器端口。-name
為容器創(chuàng)建一個名稱。-v
將文件路徑設(shè)置為容器要使用的持久卷位置。- 當 MinIO 將數(shù)據(jù)寫入 時
/data
,該數(shù)據(jù)會鏡像到本地路徑~/minio/data
,從而允許其在容器重新啟動之間保留。您可以替換~/minio/data
為用戶具有讀取、寫入和刪除訪問權(quán)限的另一個本地文件位置。 -e
分別設(shè)置環(huán)境變量MINIO_ROOT_USER
和MINIO_ROOT_PASSWORD
。這些設(shè)置root 用戶憑據(jù)。更改用于您的容器的示例值。
運行結(jié)果
WARNING: MINIO_ACCESS_KEY and MINIO_SECRET_KEY are deprecated.
Please use MINIO_ROOT_USER and MINIO_ROOT_PASSWORD
Formatting 1st pool, 1 set(s), 1 drives per set.
WARNING: Host local has more than 0 drives of set. A host failure will result in data becoming unavailable.
MinIO Object Storage Server
Copyright: 2015-2023 MinIO, Inc.
License: GNU AGPLv3 <https://www.gnu.org/licenses/agpl-3.0.html>
Version: RELEASE.2023-08-29T23-07-35Z (go1.19.12 linux/amd64)
Status: 1 Online, 0 Offline.
S3-API: http://172.17.0.2:9000 http://127.0.0.1:9000
Console: http://172.17.0.2:9090 http://127.0.0.1:9090
Documentation: https://min.io/docs/minio/linux/index.html
Warning: The standard parity is set to 0. This can lead to data loss.
4.登錄 控制臺 http://127.0.0.1:9090/browser 用戶名密碼是你啟動時初始化的這里是 minio、minio123
5.創(chuàng)建 桶(Buckets)
參考:
https://min.io/docs/minio/container/index.html
Spring Boot 集成
1. 添加 MinIO 客戶端依賴
在您的 Spring Boot 項目的 pom.xml
文件中添加 MinIO 客戶端依賴:
<dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.5.5</version> </dependency>
接下來,您需要在您的Spring Boot應(yīng)用程序中配置MinIO客戶端。您可以在 application.properties
或 application.yml
文件中添加以下配置:
# MinIO配置 minio.endpoint=http://localhost:9000 # MinIO服務(wù)器的地址 minio.access-key=minio # 您的訪問密鑰 minio.secret-key=minio123 # 您的秘密密鑰
2. 創(chuàng)建 MinIO 配置類
創(chuàng)建一個配置類,用于初始化 MinIO 客戶端。創(chuàng)建一個名為 MinioConfig
的類:
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.endpoint}") private String endpoint; @Value("${minio.access-key}") private String accessKey; @Value("${minio.secret-key}") private String secretKey; @Bean public MinioClient minioClient() { return MinioClient.builder() .endpoint(endpoint) .credentials(accessKey, secretKey) .build(); } }
3. 集成 MinIO 操作到您的應(yīng)用
您可以在您的服務(wù)或控制器中使用 MinioClient
來進行 MinIO 操作。以下是一個上傳文件到 MinIO 的示例:
import io.minio.GetObjectArgs; import io.minio.GetObjectResponse; import io.minio.MinioClient; import io.minio.PutObjectArgs; import okhttp3.Headers; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.InputStreamResource; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.UUID; @RestController @RequestMapping("/minio") public class MinioController { @Autowired private MinioClient minioClient; @PostMapping("/upload") public String uploadFile(@RequestParam("file") MultipartFile file) { try { /** * 使用 UUID 作為對象名稱: * 1. 唯一性,避免對象名稱沖突。 * 2. 隱藏實際文件信息,提高一定的隱私。 * 3. 對象名稱不受原始文件名長度或特殊字符的限制。 * 在實際場景中,如果你更注重文件的可識別性和管理,可以考慮使用文件名稱。如果你更注重唯一性和隱私性,可以考慮使用 UUID。 * 同時,你也可以結(jié)合兩者,例如將文件名作為對象屬性存儲,然后使用 UUID 作為對象名稱。這樣既可以保留文件信息,又能保證唯一性。 */ String objectName = UUID.randomUUID().toString(); Map<String, String> metadata = new HashMap<>(); metadata.put("originalFilename", file.getOriginalFilename()); minioClient.putObject( PutObjectArgs.builder() .bucket("firsttest") .object(objectName) .userMetadata(metadata) .stream(file.getInputStream(), file.getSize(), -1) .contentType(file.getContentType()) .build() ); return "File uploaded successfully! fileId: " + objectName; } catch (Exception e) { return "Error uploading file: " + e.getMessage(); } } @GetMapping("/download/{filename}") public ResponseEntity<InputStreamResource> downloadFile(@PathVariable("filename") String filename) { try { Optional<GetObjectResponse> inputStream = Optional.ofNullable(minioClient.getObject( GetObjectArgs.builder() .bucket("firsttest") .object(filename) .build() )); if (inputStream.isPresent()) { InputStreamResource resource = new InputStreamResource(inputStream.get()); Headers headers = inputStream.get().headers(); ResponseEntity.BodyBuilder bodyBuilder = ResponseEntity.ok(); String mediaType = headers.get("Content-Type"); if (StringUtils.isNotEmpty(mediaType)) { bodyBuilder.contentType(MediaType.parseMediaType(mediaType)); } return bodyBuilder.header("Content-Disposition", "attachment; filename=" + URLEncoder.encode(headers.get("X-Amz-Meta-originalfilename"), StandardCharsets.UTF_8)) .body(resource); } else { return ResponseEntity.notFound().build(); } } catch (Exception e) { return ResponseEntity.badRequest().body(null); } } }
使用 UUID 作為對象名稱:
- 唯一性,避免對象名稱沖突。
- 隱藏實際文件信息,提高一定的隱私。
- 對象名稱不受原始文件名長度或特殊字符的限制。
在實際場景中,如果你更注重文件的可識別性和管理,可以考慮使用文件名稱。如果你更注重唯一性和隱私性,可以考慮使用 UUID。同時,你也可以結(jié)合兩者,例如將文件名作為對象屬性存儲,然后使用 UUID 作為對象名稱。這樣既可以保留文件信息,又能保證唯一性。
http://127.0.0.1:80/minio/upload
上傳完畢成功后,控制臺查看文件
自定義 metadata 為啥前綴有 X-Amz-Meta-?
在 MinIO 中,當你設(shè)置自定義元數(shù)據(jù)(metadata)時,MinIO 會遵循 Amazon S3 的元數(shù)據(jù)規(guī)范,其中元數(shù)據(jù)的鍵名> 前會添加
x-amz-meta-
前綴。這是因為 MinIO 是一個兼容 Amazon S3 API 的對象存儲服務(wù)器,因此它采用了 Amazon > S3 的一些規(guī)范和約定。Amazon S3 使用
x-amz-meta-
前綴來標識用戶自定義的元數(shù)據(jù),以便與 Amazon S3 內(nèi)部使用的標準元數(shù)據(jù)進行區(qū)> 分。這樣可以確保用戶自定義的元數(shù)據(jù)不會與 S3 內(nèi)部使用的元數(shù)據(jù)沖突。這也是為了保持兼容性,使 MinIO 用戶可以> 使用與 Amazon S3 相同的元數(shù)據(jù)命名約定。因此,在 MinIO 中設(shè)置自定義元數(shù)據(jù)時,不需要手動添加
x-amz-meta-
前綴,MinIO 會自動處理這個前綴,確保它符合 Amazon S3 的規(guī)范。當你從對象中檢索元數(shù)據(jù)時,MinIO 也會自動解析并返回合適的鍵名,不包含前綴。總之,這個前綴是 MinIO 為了兼容 Amazon S3 API,保持統(tǒng)一性而引入的。
請注意,上述示例僅為基本示例,用于展示如何在Spring Boot中集成MinIO。您可以根據(jù)您的實際需求進行更多的配置和操作。確保替換示例中的"your-access-key"、“your-secret-key”、"your-bucket-name"和其他參數(shù)為您自己的值。
最后,不要忘記在您的MinIO服務(wù)器上創(chuàng)建對應(yīng)的存儲桶(Bucket),以及設(shè)置正確的訪問權(quán)限。
到此這篇關(guān)于在 Spring Boot 中集成 MinIO 對象存儲的文章就介紹到這了,更多相關(guān)Spring Boot集成 MinIO 對象存儲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- minio的下載和springboot整合minio使用方法
- SpringBoot整合Minio實現(xiàn)圖片上傳功能
- SpringBoot整合Minio實現(xiàn)文件上傳和讀取功能
- springboot整合minio的超詳細教程
- 可能是全網(wǎng)最詳細的springboot整合minio教程
- SpringBoot整合MinIO實現(xiàn)文件上傳的方法詳解
- Spring?Boot?3?整合?MinIO?實現(xiàn)分布式文件存儲的全過程
- SpringBoot+MinIO實現(xiàn)對象存儲方式
- Vue?+?SpringBoot?實現(xiàn)文件的斷點上傳、秒傳存儲到Minio的操作方法
相關(guān)文章
基于Java將Excel科學(xué)計數(shù)法解析成數(shù)字
這篇文章主要介紹了基于Java將Excel科學(xué)計數(shù)法解析成數(shù)字,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-09-09SpringData JPA審計功能(@CreatedDate與@LastModifiedDate)實現(xiàn)
Spring Data JPA的審計功能提供了一種強大而靈活的機制,用于自動跟蹤實體的創(chuàng)建和修改信息,通過使用@CreatedDate和@LastModifiedDate注解,開發(fā)者可以輕松地實現(xiàn)時間審計,感興趣的可以了解一下2025-04-04spring boot配置ssl實現(xiàn)HTTPS的方法
這篇文章主要介紹了spring boot配置ssl實現(xiàn)HTTPS的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-03-03一文探究ArrayBlockQueue函數(shù)及應(yīng)用場景
這篇文章主要為大家介紹了一文探究ArrayBlockQueue函數(shù)及應(yīng)用場景,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03SpringBoot集成Tess4J實現(xiàn)OCR的示例代碼
Tess4J是一個基于Tesseract OCR引擎的Java接口,可以用來識別圖像中的文本,說白了,就是封裝了它的API,讓Java可以直接調(diào)用,本文給大家介紹了SpringBoot集成Tess4J實現(xiàn)OCR的示例,需要的朋友可以參考下2024-12-12maven自動將源碼打包并發(fā)布的實現(xiàn)步驟
maven-source-plugin 提供項目自動將源碼打包并發(fā)布的功能,在需要發(fā)布源碼項目的 pom.xml 文件中添加即可,本文就來介紹一下如何設(shè)置,感興趣的可以了解一下2023-11-11關(guān)于SpringBoot mysql數(shù)據(jù)庫時區(qū)問題
在后端開發(fā)過程中經(jīng)常會遇到幾個時區(qū)設(shè)置問題,今天分幾種情況給大家介紹SpringBoot mysql數(shù)據(jù)庫時區(qū)問題,感興趣的朋友跟隨小編一起看看吧2021-06-06SpringMVC源碼之HandlerMapping處理器映射器解析
這篇文章主要介紹了SpringMVC源碼之HandlerMapping處理器映射器解析,在Spring?MVC中,HandlerMapping處理器映射器用于確定請求處理器對象,請求處理器可以是任何對象,只要它們使用了@Controller注解或注解@RequestMapping,需要的朋友可以參考下2023-08-08