1.docker部署Minio
1.1 创建docker-compose-minio.yml文件
# 可参考 https://docs.min.io/docs/minio-docker-quickstart-guide.html
version: '3'
services:
minio:
image: minio/minio:latest # 原镜像`minio/minio:latest`
container_name: minio # 容器名为'minio'
restart: unless-stopped # 指定容器退出后的重启策略为始终重启,但是不考虑在Docker守护进程启动时就已经停止了的容器
volumes: # 数据卷挂载路径设置,将本机目录映射到容器目录
- "./minio/data:/data"
- "./minio/minio:/minio"
- "./minio/config:/root/.minio"
environment: # 设置环境变量,相当于docker run命令中的-e
TZ: Asia/Shanghai
LANG: en_US.UTF-8
MINIO_PROMETHEUS_AUTH_TYPE: "public"
MINIO_ACCESS_KEY: "minioadmin" # 登录账号
MINIO_SECRET_KEY: "minioadmin" # 登录密码
command: server /data --console-address ":9001"
logging:
driver: "json-file"
options:
max-size: "100m"
ports: # 映射端口
- "9000:9000" # 文件上传&预览端口
- "9001:9001" # 控制台访问端口
1.2 部署minio
docker-compose -f docker-compose-minio.yml -p minio up -d
1.3 开放端口9000、9001
firewall-cmd --zone=public --add-port=9000/tcp --permanent
firewall-cmd --zone=public --add-port=9001/tcp --permanent
## 重启防火墙
firewall-cmd --reload
## 查看端口开放情况
firewall-cmd --zone=public --list-ports
1.4 登录minio并创建桶
创建Access Keys,下载,保存好。
2. 创建SpringBoot项目
2.1 pom文件添加依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.2</version>
</dependency>
2.2 application.yml添加配置
#minio配置(下面四个都要替换成自己的)
minio:
access-key: 4oaTwt4xxxx
secret-key: 3s8p8AAhxxxxxx
url: http://192.xxxx:9000
bucket-name: xxxxxx
2.3 编写MinioConfig配置类
package com.minio.config;
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 accessKey;
private String secretKey;
private String url;
private String bucketName;
@Bean
public MinioClient minioClient(){
return MinioClient.builder()
.region("cn-north-1")
.endpoint(url)
.credentials(accessKey,secretKey)
.build();
}
}
2.4 编写MinioUtil工具类
package com.minio.utils;
import com.minio.config.MinioConfig;
import io.minio.*;
import io.minio.http.Method;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.concurrent.TimeUnit;
@Component
public class MinioUtil {
@Autowired
private MinioClient minioClient;
@Autowired
private MinioConfig configuration;
/**
* 判断bucket是否存在,不存在则创建
*/
public boolean existBucket(String bucketName) {
boolean exists;
try {
exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
if (!exists) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
exists = true;
}
} catch (Exception e) {
e.printStackTrace();
exists = false;
}
return exists;
}
/**
* 删除bucket
*/
public Boolean removeBucket(String bucketName) {
try {
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 上传文件
*
* @param file 文件
* @param fileName 文件名称
*/
public void upload(MultipartFile file, String fileName) {
// 使用putObject上传一个文件到存储桶中。
try {
InputStream inputStream = file.getInputStream();
minioClient.putObject(PutObjectArgs.builder()
.bucket(configuration.getBucketName())
.object(fileName)
.stream(inputStream, file.getSize(), -1)
.contentType(file.getContentType())
.build());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取文件访问地址(有过期时间)
*
* @param fileName 文件名称
* @param time 时间
* @param timeUnit 时间单位
*/
public String getExpireFileUrl(String fileName, int time, TimeUnit timeUnit) {
try {
return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(configuration.getBucketName())
.object(fileName)
.expiry(time, timeUnit).build());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取文件访问地址
*
* @param fileName 文件名称
*/
public String getFileUrl(String fileName) {
try {
return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(configuration.getBucketName())
.object(fileName)
.build()
);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 下载文件
*
* @param fileName 文件名称
*/
public void download(HttpServletResponse response, String fileName) {
InputStream in = null;
try {
// 获取对象信息
StatObjectResponse stat = minioClient.statObject(StatObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());
response.setContentType(stat.contentType());
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
// 文件下载
in = minioClient.getObject(GetObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());
IOUtils.copy(in, response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 删除文件
*
* @param fileName 文件名称
*/
public void delete(String fileName) {
try {
minioClient.removeObject(RemoveObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.5 编写UploadController
package com.minio.controller;
import com.minio.utils.MinioUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
@RestController
@RequestMapping("/api")
public class UploadController {
@Autowired
private MinioUtil minioUtil;
/**
* 上传文件
*/
@PostMapping(value = "/upload")
public String uploadReport(MultipartFile[] files) {
for (MultipartFile file : files) {
String fileName = file.getOriginalFilename();
String rename = UUID.randomUUID().toString();
minioUtil.upload(file, rename);
}
return "上传成功";
}
/**
* 预览文件
*/
@GetMapping("/preview")
public String preview(String fileName) {
return minioUtil.getFileUrl(fileName);
}
/**
* 下载文件
*/
@GetMapping("/download")
public void download(String fileName, HttpServletResponse response) {
minioUtil.download(response, fileName);
}
/**
* 删除文件
*/
@GetMapping("/delete")
public String delete(String fileName) {
minioUtil.delete(fileName);
return "删除成功";
}
}