- Docker安装MinIO
1.添加依赖Demo 地址:mingyue-springboot-minio
2.修改配置文件io.minio minio 8.3.9 com.squareup.okhttp3 okhttp 4.9.0
minio: endpoint: http://IP:9000 port: 9000 accessKey: 登录账号 secretKey: 登录密码 secure: false bucket-name: mingyue-test # 桶名 image-size: 10485760 # 图片文件的最大大小 file-size: 1073741824 # 文件的最大大小3.创建 Minio 配置类
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioPropertiesConfig {
private String endpoint;
private Integer port;
private String accessKey;
private String secretKey;
private boolean secure;
private String bucketName;
private long imageSize;
private long fileSize;
@Bean
public MinioClient minioClient() {
return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
}
}
4.创建 Minio 工具类
import com.csp.mingyue.minio.config.MinioPropertiesConfig;
import io.minio.BucketExistsArgs;
import io.minio.GetObjectArgs;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.ListObjectsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveBucketArgs;
import io.minio.RemoveObjectArgs;
import io.minio.RemoveObjectsArgs;
import io.minio.Result;
import io.minio.StatObjectArgs;
import io.minio.StatObjectResponse;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
@Slf4j
@Component
@RequiredArgsConstructor
public class MinioUtil {
private final MinioPropertiesConfig minioPropertiesConfig;
private final MinioClient minioClient;
@SneakyThrows
public boolean bucketExists(String bucketName) {
boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
if (found) {
log.info("{} exists", bucketName);
} else {
log.info("{} does not exist", bucketName);
}
return found;
}
@SneakyThrows
public boolean makeBucket(String bucketName) {
boolean flag = bucketExists(bucketName);
if (!flag) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
return true;
} else {
return false;
}
}
@SneakyThrows
public List listBucketNames() {
List bucketList = listBuckets();
List bucketListName = new ArrayList<>();
for (Bucket bucket : bucketList) {
bucketListName.add(bucket.name());
}
return bucketListName;
}
@SneakyThrows
public List listBuckets() {
return minioClient.listBuckets();
}
@SneakyThrows
public boolean removeBucket(String bucketName) {
boolean flag = bucketExists(bucketName);
if (flag) {
Iterable> myObjects = listObjects(bucketName);
for (Result- result : myObjects) {
Item item = result.get();
// 有对象文件,则删除失败
if (item.size() > 0) {
return false;
}
}
// 删除存储桶,注意,只有存储桶为空时才能删除成功。
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
flag = bucketExists(bucketName);
return !flag;
}
return false;
}
@SneakyThrows
public List
listObjectNames(String bucketName) {
List listObjectNames = new ArrayList<>();
boolean flag = bucketExists(bucketName);
if (flag) {
Iterable> myObjects = listObjects(bucketName);
for (Result- result : myObjects) {
Item item = result.get();
listObjectNames.add(item.objectName());
}
} else {
listObjectNames.add("存储桶不存在");
}
return listObjectNames;
}
@SneakyThrows
public Iterable
> listObjects(String bucketName) {
boolean flag = bucketExists(bucketName);
if (flag) {
return minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());
}
return null;
}
@SneakyThrows
public void putObject(
String bucketName, MultipartFile multipartFile, String filename, String fileType) {
InputStream inputStream = new ByteArrayInputStream(multipartFile.getBytes());
minioClient.putObject(
PutObjectArgs.builder().bucket(bucketName).object(filename).stream(
inputStream, -1, minioPropertiesConfig.getFileSize())
.contentType(fileType)
.build());
}
@SneakyThrows
public String getObjectUrl(String bucketName, String objectName) {
boolean flag = bucketExists(bucketName);
String url = "";
if (flag) {
url =
minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucketName)
.object(objectName)
.expiry(2, TimeUnit.MINUTES)
.build());
log.info("url:{}", url);
}
return url;
}
@SneakyThrows
public boolean removeObject(String bucketName, String objectName) {
boolean flag = bucketExists(bucketName);
if (flag) {
minioClient.removeObject(
RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
return true;
}
return false;
}
@SneakyThrows
public InputStream getObject(String bucketName, String objectName) {
boolean flag = bucketExists(bucketName);
if (flag) {
StatObjectResponse statObject = statObject(bucketName, objectName);
if (statObject != null && statObject.size() > 0) {
return minioClient.getObject(
GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
}
}
return null;
}
@SneakyThrows
public StatObjectResponse statObject(String bucketName, String objectName) {
boolean flag = bucketExists(bucketName);
if (flag) {
return minioClient.statObject(
StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
}
return null;
}
@SneakyThrows
public boolean removeObject(String bucketName, List objectNames) {
boolean flag = bucketExists(bucketName);
if (flag) {
List objects = new LinkedList<>();
for (String objectName : objectNames) {
objects.add(new DeleteObject(objectName));
}
Iterable> results =
minioClient.removeObjects(
RemoveObjectsArgs.builder().bucket(bucketName).objects(objects).build());
for (Result result : results) {
DeleteError error = result.get();
log.info("Error in deleting object {}: {}", error.objectName(), error.message());
}
}
return true;
}
@SneakyThrows
public InputStream getObject(String bucketName, String objectName, long offset, Long length) {
boolean flag = bucketExists(bucketName);
if (flag) {
StatObjectResponse statObject = statObject(bucketName, objectName);
if (statObject != null && statObject.size() > 0) {
return minioClient.getObject(
GetObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.offset(offset)
.length(length)
.build());
}
}
return null;
}
@SneakyThrows
public boolean putObject(
String bucketName, String objectName, InputStream inputStream, String contentType) {
boolean flag = bucketExists(bucketName);
if (flag) {
minioClient.putObject(
PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(
inputStream, -1, minioPropertiesConfig.getFileSize())
.contentType(contentType)
.build());
StatObjectResponse statObject = statObject(bucketName, objectName);
return statObject != null && statObject.size() > 0;
}
return false;
}
}
5.创建 Minio Service
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.csp.mingyue.minio.config.MinioPropertiesConfig;
import com.csp.mingyue.minio.util.MinioUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@Slf4j
@Service
@RequiredArgsConstructor
public class MinioService {
private final MinioPropertiesConfig minioPropertiesConfig;
private final MinioUtil minioUtil;
public boolean bucketExists(String bucketName) {
return minioUtil.bucketExists(bucketName);
}
public void makeBucket(String bucketName) {
minioUtil.makeBucket(bucketName);
}
public String upload(MultipartFile file, String bucketName, String fileType) {
if (StrUtil.isBlank(bucketName)) {
log.info("bucketName is null");
}
try {
if (!this.bucketExists(bucketName)) {
this.makeBucket(bucketName);
}
String fileName = file.getOriginalFilename();
assert fileName != null;
String objectName =
IdUtil.randomUUID().replace("-", "") + fileName.substring(fileName.lastIndexOf("."));
minioUtil.putObject(bucketName, file, objectName, fileType);
return minioPropertiesConfig.getEndpoint() + "/" + bucketName + "/" + objectName;
} catch (Exception e) {
e.printStackTrace();
return "上传失败";
}
}
public String getObjectUrl(String bucketName, String objectName) {
return minioUtil.getObjectUrl(bucketName, objectName);
}
}
6.Minio 接口
import com.csp.mingyue.minio.config.MinioPropertiesConfig;
import com.csp.mingyue.minio.service.MinioService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
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;
@RestController
@RequestMapping("/minio")
@RequiredArgsConstructor
public class MinioController {
private final MinioPropertiesConfig minioPropertiesConfig;
private final MinioService minioService;
@PostMapping("/upload")
public String upload(@RequestParam(name = "multipartFile") MultipartFile multipartFile) {
return minioService.upload(
multipartFile, minioPropertiesConfig.getBucketName(), multipartFile.getContentType());
}
@GetMapping("/getObjectUrl")
public String getObjectUrl(String objectName) {
return minioService.getObjectUrl(minioPropertiesConfig.getBucketName(), objectName);
}
}
7.测试接口
-
Post http://127.0.0.1:8080/minio/upload 上传接口
接口返回如下:
http://ip:port/mingyue-test/60396cc92fec4e2cbb4a974d810e7115.jpg
-
Get http://127.0.0.1:8080/minio/getObjectUrl?objectName=60396cc92fec4e2cbb4a974d810e7115.jpg 查询接口
接口返回如下:
http://ip:port/mingyue-test/60396cc92fec4e2cbb4a974d810e7115.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20220425%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220425T055235Z&X-Amz-Expires=120&X-Amz-SignedHeaders=host&X-Amz-Signature=35eeffddca22f8211a1af0e936066e848a988e82b73548cfc87f2294e0861f01
只写了两个接口,想要查询桶列表或者其他功能具体看 MinioUtil 函数,主要可以参考如下文档:
- Minio中文文档
- MINIO 对象存储祼机使用文档
- Minio快速入门指南



