MinIO 是一個開源的對象存儲服務器,專注于高性能、分布式和兼容S3 API的存儲解決方案。本文將介紹如何在 Spring Boot 應用程序中集成 MinIO,以便您可以輕松地將對象存儲集成到您的應用中。
安裝minio
-
拉取 minio Docker鏡像
docker pull minio/minio
-
創(chuàng)建minio數(shù)據(jù)和配置目錄
mkdir -p /data/minio/data /data/minio/config
-
運行minio容器,設置訪問和密鑰并掛載數(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
將文件路徑設置為容器要使用的持久卷位置。當 MinIO 將數(shù)據(jù)寫入 時/data
,該數(shù)據(jù)會鏡像到本地路徑~/minio/data
,從而允許其在容器重新啟動之間保留。您可以替換~/minio/data
為用戶具有讀取、寫入和刪除訪問權限的另一個本地文件位置。 -
-e
分別設置環(huán)境變量MINIO_ROOT_USER
和MINIO_ROOT_PASSWORD
。這些設置root 用戶憑據(jù)。更改用于您的容器的示例值。
運行結果
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.
- 登錄 控制臺 http://127.0.0.1:9090/browser 用戶名密碼是你啟動時初始化的這里是 minio、minio123
- 創(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應用程序中配置MinIO客戶端。您可以在application.properties
或application.yml
文件中添加以下配置:
# MinIO配置
minio.endpoint=http://localhost:9000 # MinIO服務器的地址
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 操作到您的應用
您可以在您的服務或控制器中使用 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。
* 同時,你也可以結合兩者,例如將文件名作為對象屬性存儲,然后使用 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。
同時,你也可以結合兩者,例如將文件名作為對象屬性存儲,然后使用 UUID 作為對象名稱。這樣既可以保留文件信息,又能保證唯一性。
http://127.0.0.1:80/minio/upload
上傳完畢成功后,控制臺查看文件
自定義 metadata 為啥前綴有 X-Amz-Meta-?
在 MinIO 中,當你設置自定義元數(shù)據(jù)(metadata)時,MinIO 會遵循 Amazon S3 的元數(shù)據(jù)規(guī)范,其中元數(shù)據(jù)的鍵名> 前會添加
x-amz-meta-
前綴。這是因為 MinIO 是一個兼容 Amazon S3 API 的對象存儲服務器,因此它采用了 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ù)據(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ù)為您自己的值。文章來源:http://www.zghlxwxcb.cn/news/detail-685183.html
最后,不要忘記在您的MinIO服務器上創(chuàng)建對應的存儲桶(Bucket),以及設置正確的訪問權限。文章來源地址http://www.zghlxwxcb.cn/news/detail-685183.html
到了這里,關于在 Spring Boot 中集成 MinIO 對象存儲的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!