MinIO Docker安装使用和整合
Docker安装
docker run \
-p 9000:9000 \
-p 9001:9001 \
--name minio \
-d --restart=always \
-e "MINIO_ROOT_USER=minioadmin" \
-e "MINIO_ROOT_PASSWORD=minioadmin" \
-e "MINIO_BROWSER_DEFAULT_LOCALE=zh_CN" \ # 这个好像没啥用
-v /opt/minio/data:/data \
-v /opt/minio/config:/root/.minio \
minio/minio server \
/data --console-address ":9001" -address ":9000"
SpringBoot整合
maven
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.12</version>
</dependency>
Configuration
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
private String url;
private String accessKey;
private String secretKey;
private String bucket;
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint(url)
.credentials(accessKey, secretKey)
.build();
}
}
YAML
spring:
application:
name: jelly-minio
servlet:
multipart:
enabled: true
max-file-size: 100MB
max-request-size: 100MB
server:
port: 8088
servlet:
context-path: /minio
minio:
url: http://192.168.83.128:9000
accessKey: minioadmin
secretKey: minioadmin
bucket: blog
Util工具类
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Component
public class MinioUtil {
@Autowired
private MinioClient client;
@Value("${minio.bucket}")
private String bucketName;
public boolean bucketExists(String bucketName) {
try {
BucketExistsArgs bucketArgs = BucketExistsArgs
.builder().bucket(bucketName).build();
return client.bucketExists(bucketArgs);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void createBucket(String bucketName) {
try {
if (!bucketExists(bucketName)) {
MakeBucketArgs args = MakeBucketArgs.builder()
.bucket(bucketName)
.build();
client.makeBucket(args);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void deleteBucket(String bucketName) {
try {
if (bucketExists(bucketName)) {
RemoveBucketArgs args = RemoveBucketArgs.builder().bucket(bucketName).build();
client.removeBucket(args);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Optional<Bucket> getBucket(String bucketName) {
try {
return client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public List<Bucket> listBuckets() {
try {
return client.listBuckets();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String getBucketPolicy(String bucketName) {
try {
return client.getBucketPolicy(
GetBucketPolicyArgs.builder().bucket(bucketName).build());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void setBucketPolicy(String bucketName, String config) {
try {
SetBucketPolicyArgs args = SetBucketPolicyArgs.builder()
.bucket(bucketName)
.config(config)
.build();
client.setBucketPolicy(args);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public boolean isObjectExist(String bucketName, String objectName) {
try {
StatObjectArgs args = StatObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build();
return client.statObject(args).size() > 0;
} catch (Exception e) {
return false;
}
}
public ObjectWriteResponse createFolder(String bucketName, String objectName) {
try {
return client.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.stream(new ByteArrayInputStream(new byte[]{}), 0, -1)
.build());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public List<Item> listObjectsByPrefix(String bucketName, String prefix, boolean recursive) {
List<Item> itemList = new ArrayList<>();
try {
ListObjectsArgs args = ListObjectsArgs.builder()
.bucket(bucketName)
.prefix(prefix)
.recursive(recursive)
.build();
Iterable<Result<Item>> items = client.listObjects(args);
if (items != null) {
for (Result<Item> result : items) {
Item item = result.get();
itemList.add(item);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return itemList;
}
public InputStream getObject(String bucketName, String objectName) {
try {
GetObjectArgs args = GetObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build();
return client.getObject(args);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public InputStream getObject(String bucketName, String objectName, long offset, long length) {
try {
GetObjectArgs args = GetObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.offset(offset)
.length(length)
.build();
return client.getObject(args);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Iterable<Result<Item>> listObjects(String bucketName, String prefix, boolean recursive) {
try {
ListObjectsArgs args = ListObjectsArgs.builder()
.bucket(bucketName)
.prefix(prefix)
.recursive(recursive)
.build();
return client.listObjects(args);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public ObjectWriteResponse uploadFile(String bucketName, MultipartFile file, String objectName, String contentType) throws IOException {
InputStream inputStream = file.getInputStream();
try {
return client.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.contentType(contentType)
.stream(inputStream, inputStream.available(), -1)
.build());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String upload(String bucketName, String fileName, String filePath) {
try {
UploadObjectArgs args = UploadObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.filename(filePath)
.build();
client.uploadObject(args);
return client.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucketName)
.object(fileName)
.expiry(2, TimeUnit.HOURS)
.build());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public ObjectWriteResponse uploadImage(String bucketName, String imageBase64, String imageName) {
Assert.notNull(imageBase64, "imageBase64 can not be null");
byte[] decode = Base64.getDecoder().decode(imageBase64);
InputStream in = new ByteArrayInputStream(decode);
String newName = System.currentTimeMillis() + "_" + imageName + ".jpg";
String year = String.valueOf(new Date().getYear());
String month = String.valueOf(new Date().getMonth());
return uploadFile(bucketName, year + "/" + month + "/" + newName, in);
}
public ObjectWriteResponse uploadFile(String bucketName, String objectName, String fileName) {
try {
return client.uploadObject(
UploadObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.filename(fileName)
.build());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public ObjectWriteResponse uploadFile(String bucketName, String objectName, InputStream inputStream) {
try {
return client.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.stream(inputStream, inputStream.available(), -1)
.build());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public boolean removeFile(String bucketName,String fileName) {
try {
RemoveObjectArgs args = RemoveObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.build();
client.removeObject(args);
return true;
} catch (Exception e) {
return false;
}
}
public void removeFiles(String bucketName, List<String> keys) {
List<DeleteObject> objects = new LinkedList<>();
keys.forEach(s -> {
objects.add(new DeleteObject(s));
try {
removeFile(bucketName, s);
} catch (Exception e) {
}
});
}
public String getFileStatusInfo(String bucketName, String objectName) {
try {
return client.statObject(
StatObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build()).toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public ObjectWriteResponse copyFile(String bucketName, String objectName, String srcBucketName, String srcObjectName) {
try {
return client.copyObject(
CopyObjectArgs.builder()
.source(CopySource.builder().bucket(bucketName).object(objectName).build())
.bucket(srcBucketName)
.object(srcObjectName)
.build());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@SneakyThrows(Exception.class)
public String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) {
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
.expiry(expires)
.bucket(bucketName)
.object(objectName).build();
return client.getPresignedObjectUrl(args);
}
@SneakyThrows(Exception.class)
public String getPresignedObjectUrl(String bucketName, String objectName) {
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
.bucket(bucketName)
.object(objectName)
.method(Method.GET).build();
return client.getPresignedObjectUrl(args);
}
}
Test
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.ClassPathResource;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Optional;
@SpringBootTest
class JellyMinioApplicationTests {
@Autowired
private MinioUtil minioUtil;
@Test
void upload() {
String filename ="2024/X_4.jpg";
String path="C:\\Users\\xiaohao\\Pictures\\4K壁纸\\X_4.jpg";
String url= minioUtil.upload("blog",filename, path);
System.out.println(url);
}
@Test
void createBucket() {
minioUtil.createBucket("myblog");
}
@Test
void bucketExists() {
boolean exists = minioUtil.bucketExists("myblog");
System.out.println(exists);
}
@Test
void deleteBucket() {
minioUtil.deleteBucket("myblog");
}
@Test
void getBucketPolicy() {
String bucketPolicy = minioUtil.getBucketPolicy("myblog");
System.out.println(bucketPolicy);
}
@Test
void setBucketPolicy() throws IOException {
ClassPathResource classPathResource = new ClassPathResource("a3.json");
InputStream inputStream = classPathResource.getInputStream();
String config = new String(inputStream.readAllBytes());
minioUtil.setBucketPolicy("myblog", config);
}
@Test
void listBuckets() {
List<Bucket> buckets = minioUtil.listBuckets();
for (Bucket bucket : buckets) {
System.out.println(bucket.name());
}
}
@Test
void getBuckets() {
Optional<Bucket> bucket = minioUtil.getBucket("myblog");
System.out.println(bucket.get().name());
}
@Test
void isObjectExist() {
boolean objectExist = minioUtil.isObjectExist("blog", "X_4.jpg");
System.out.println(objectExist);
}
@Test
void listObjectsByPrefix() {
List<Item> items = minioUtil.listObjectsByPrefix("blog", "2", true);
for (Item item : items) {
System.out.println(item.objectName());
}
}
@Test
void getFileStatusInfo(){
String fileStatusInfo = minioUtil.getFileStatusInfo("blog", "X_4.jpg");
System.out.println(fileStatusInfo);
}
@Test
void getPresignedObjectUrl(){
String presignedObjectUrl = minioUtil.getPresignedObjectUrl("blog", "X_4.jpg");
System.out.println(presignedObjectUrl);
}
@Test
void createFile(){
minioUtil.createFolder("blog", "/2024/1/1/");
String filename ="/2024/1/1/X_7.png";
String path="C:\\Users\\xiaohao\\Pictures\\4K壁纸\\X_7.png";
String url= minioUtil.upload("blog",filename, path);
System.out.println(url);
}
}
MinIO config 配置桶政策
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"*"
]
},
"Action": [
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::myblog"
]
},
{
"Effect": "Allow",
"Principal": {
"AWS": [
"*"
]
},
"Action": [
"s3:AbortMultipartUpload",
"s3:DeleteObject",
"s3:GetObject",
"s3:ListMultipartUploadParts",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::myblog/*"
]
}
]
}