1. docker-compose安装
新建文件夹
mkdir -p /opt/app/minio && mkdir -p /opt/app/minio/data && mkdir -p /opt/app/minio/config
cd /opt/app/minio
vim docker-compose.yml
version: '3.0'
services:
minio:
image: minio/minio
container_name: minio
restart: always
ports:
- 9000:9000
- 9001:9001
command: server /data --console-address ":9001" #指定容器中的目录 /data
environment:
MINIO_ACCESS_KEY: minioadmin #管理后台用户名
MINIO_SECRET_KEY: minioadmin #管理后台密码,最小8个字符
volumes:
- ./data:/data #映射当前目录下的data目录至容器内/data目录
- ./config:/root/.minio/ #映射配置目录
访问控制台 http://ip:9001/
2. spirngboot
pom
<!-- minio 依赖 -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.3.9</version>
</dependency>
<!-- minio 依赖于 okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.0</version>
</dependency>
yml minio 配置
minio:
endpoint: http://192.168.202.128:9000
port: 9000
accessKey: minioadmin
secretKey: minioadmin
secure: false
bucket-name: xbb # 桶名
image-size: 10485760 # 图片文件的最大大小
file-size: 1073741824 # 文件的最大大小
MinioConfig
/**
* Minio 配置
*/
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
/** 服务地址 */
private String endpoint;
/** TCP/IP端口号 */
private Integer port;
/** 账户 */
private String accessKey;
/** 密码 */
private String secretKey;
/** 如果是 true,则用的是 https 而不是 http,默认值是 true" */
private boolean secure;
/** 存储桶 */
private String bucketName;
/** 图片的最大大小 */
private long imageSize;
/** 其他文件的最大大小 */
private long fileSize;
/** 初始化 MinIO 客户端 */
@Bean
public MinioClient minioClient() {
return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
}
}
MinioService
@Slf4j
@Component
@RequiredArgsConstructor
public class MinioService {
private final MinioConfig minioConfig;
private final MinioClient minioClient;
/** 文件上传 */
public String upload(MultipartFile file) {
String bucketName = minioConfig.getBucketName();
try {
if (!this.bucketExists(bucketName)) {
this.makeBucket(bucketName);
}
String fileName = file.getOriginalFilename();
assert fileName != null;
String objectName =
IdUtil.randomUUID().replace("-", "") + fileName.substring(fileName.lastIndexOf("."));
this.putObject(bucketName, file, objectName, file.getContentType());
return minioConfig.getEndpoint() + "/" + bucketName + "/" + objectName;
} catch (Exception e) {
log.error("文字上传失败", e);
return null;
}
}
/**
* 检查存储桶是否存在
*
* @param bucketName 存储桶名称
*/
@SneakyThrows
public boolean bucketExists(String bucketName) {
return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
}
/**
* 创建存储桶
*
* @param bucketName 存储桶名称
*/
@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<Bucket> listBuckets() {
return minioClient.listBuckets();
}
/**
* 列出存储桶中的所有对象
*
* @param bucketName 存储桶名称
*/
@SneakyThrows
public Iterable<Result<Item>> listObjects(String bucketName) {
boolean flag = bucketExists(bucketName);
if (flag) {
return minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());
}
return null;
}
/**
* 文件上传
*
* @param bucketName 桶名称
* @param multipartFile 上传的文件
*/
@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, minioConfig.getFileSize())
.contentType(fileType)
.build());
}
/**
* 获取对象的元数据
*
* @param bucketName 存储桶名称
* @param objectName 存储桶里的对象名称
*/
@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;
}
}
CommonController
@RestController
@RequestMapping("/common")
@Slf4j
public class CommonController {
@Autowired private MinioService minioService;
@PostMapping("/upload")
public String upload(@RequestParam(name = "file") MultipartFile file) {
return minioService.upload(file);
}
}
3. 测试
postman请求上传图片后返回url, 图片不可访问
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied.</Message>
<Key>7dc4086b79f04b6aa17a9c86568d5bf5.jpg</Key>
<BucketName>xbb</BucketName>
<Resource>/xbb/7dc4086b79f04b6aa17a9c86568d5bf5.jpg</Resource>
<RequestId>17182108A38E78D8</RequestId>
<HostId>4c4c25a2-6ca6-4504-9e6b-53d07bc1b774</HostId>
</Error>
登录minio控制台 ip:9000,修改 bucket 为 public 后,图片可正常访问。