一、MinIo的安装及启动
1、ubuntu系统(使用docker,安装更简单)
# 1、搜索minio镜像
docker search minio
# 2、拉取镜像
docker pull minio/minio
# 3、创建minio存放目录(改为自己的目录)
mkdir -p /opt/docker/minio/data
# 4、启动minio并指定端口(可改为自己指定的映射端口和挂载目录)
docker run -p 9000:9000 -p 5001:5001 --name minio -v /opt/docker/minio/data:/data \
-e "MINIO_ROOT_USER=admin" -e "MINIO_ROOT_PASSWORD=minioadmin" \
-d minio/minio server /data --console-address ":5001"
# 5、设置docker启动后minio自动启动
docker update --restart=always
# 6、MinIO启动后,在浏览器地址栏中输入http://ip:9000,打开后自动跳转到http://ip:5001,输入用户名和密码(admin/minioadmin)即可登陆系统
2、ubuntu系统(不使用docker)
(1)安装minIO
# 1、下载minIO服务端
wget https://dl.min.io/server/minio/release/linux-amd64/minio
# 2、将下载所得minio文件拷贝到指定文件夹并赋权
sudo cp minio /usr/local/bin/
sudo chmod +x /usr/local/bin/minio
# 3、设置对象存储位置
sudo mkdir /opt/docker/minio/data
(2)配置minIO服务自启动
a)默认把配置文件放入/etc/default文件夹中,名称为minio
sudo nano /etc/default/minio
b)写入如下内容
# 指定数据存储目录
MINIO_VOLUMES="/opt/docker/minio/data"
# 监听端口
MINIO_OPTS="--address :9000 --console-address :5001"
# 指定默认的用户名和密码,其中用户名必须大于3个字母,否则不能启动
MINIO_ROOT_USER="admin"
MINIO_ROOT_PASSWORD="minioadmin"
# 区域值,标准格式是“国家-区域-编号”,
MINIO_REGION="cn-north-1"
c)编写服务文件
sudo nano /usr/lib/systemd/system/minio.service
d)写入如下内容
[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio
[Service]
WorkingDirectory=/usr/local/
ProtectProc=invisible
# 指向上面的配置文件
EnvironmentFile=/etc/default/minio
ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
# Let systemd restart this service always
Restart=always
# Specifies the maximum (1M) file descriptor number that can be opened by this process
LimitNOFILE=1048576
# Specifies the maximum number of threads this process can create
TasksMax=infinity
# Disable timeout logic and wait until process is stopped
TimeoutStopSec=infinity
SendSIGKILL=no
SuccessExitStatus=0
[Install]
WantedBy=multi-user.target
Alias=minio.service
e)使minIO服务生效
# 1、重新加载服务配置文件,使服务生效
systemctl daemon-reload
# 2、将服务设置为开机启动
systemctl enable minio
# 3、服务立即启动
systemctl start minio
# 4、查看minio服务当前状态
systemctl status minio
f)MinIO启动后,在浏览器地址栏中输入http://ip:9000,打开后自动跳转到http://ip:5001,输入用户名和密码(admin/minioadmin)即可登陆系统。
二、SpringBoot整合MinIO
1、在springboot项目的pom.xml中导入依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.2</version>
</dependency>
2、在springboot项目的application.yml中进行配置
minio:
endpoint: http://127.0.0.1:9000 # Minio服务所在地址,改成自己的minIO服务地址
bucketName: tulaoda # 存储桶名称(可改)
accessKey: admin # minIO账号
secretKey: minioadmin # minIO密码
3、创建MinioConfig.class配置类
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
private String endpoint;
private String accessKey;
private String secretKey;
private String bucketName;
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
}
}
4、创建minio工具类
@Component
@Slf4j
public class MinioUtil {
@Autowired
private MinioConfig prop;
@Resource
private MinioClient minioClient;
@Autowired
private CodeService codeService;
/**
* 查看存储bucket是否存在
* @return boolean
*/
public Boolean bucketExists(String bucketName) {
Boolean found;
try {
found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return found;
}
/**
* 创建存储bucket
* @return Boolean
*/
public Boolean makeBucket(String bucketName) {
try {
minioClient.makeBucket(MakeBucketArgs.builder()
.bucket(bucketName)
.build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 删除存储bucket
* @return Boolean
*/
public Boolean removeBucket(String bucketName) {
try {
minioClient.removeBucket(RemoveBucketArgs.builder()
.bucket(bucketName)
.build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 获取全部bucket
*/
public List<Bucket> getAllBuckets() {
try {
List<Bucket> buckets = minioClient.listBuckets();
return buckets;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 文件上传
* @param file 文件
* @return Boolean
*/
public String upload(MultipartFile file) {
String originalFilename = file.getOriginalFilename();
if (StringUtils.isBlank(originalFilename)) {
throw new RuntimeException();
}
String fileName = UUIDUtil.getUuid() + originalFilename.substring(originalFilename.lastIndexOf("."));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String objectName = sdf.format(new Date()) + "/" + fileName;
try {
if(!bucketExists(prop.getBucketName())) {
makeBucket(prop.getBucketName()); // 创建存储bucket
}
PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(prop.getBucketName()).object(objectName)
.stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
//文件名称相同会覆盖
minioClient.putObject(objectArgs);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return objectName;
}
/**
* 预览图片
* @param fileName
* @return
*/
public String preview(String fileName){
// 查看文件地址
GetPresignedObjectUrlArgs build = new GetPresignedObjectUrlArgs().builder().bucket(prop.getBucketName()).object(fileName).method(Method.GET).build();
try {
String url = minioClient.getPresignedObjectUrl(build);
return url;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 文件下载
* @param fileName 文件名称
* @param res response
* @return Boolean
*/
public void download(String fileName, HttpServletResponse res) {
GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(prop.getBucketName())
.object(fileName).build();
try (GetObjectResponse response = minioClient.getObject(objectArgs)){
byte[] buf = new byte[1024];
int len;
try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()){
while ((len=response.read(buf))!=-1){
os.write(buf,0,len);
}
os.flush();
byte[] bytes = os.toByteArray();
res.setCharacterEncoding("utf-8");
// 设置强制下载不打开
// res.setContentType("application/force-download");
res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
try (ServletOutputStream stream = res.getOutputStream()){
stream.write(bytes);
stream.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 查看文件对象
* @return 存储bucket内文件对象信息
*/
public List<Item> listObjects() {
Iterable<Result<Item>> results = minioClient.listObjects(
ListObjectsArgs.builder().bucket(prop.getBucketName()).build());
List<Item> items = new ArrayList<>();
try {
for (Result<Item> result : results) {
items.add(result.get());
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return items;
}
/**
* 删除
* @param fileName
* @return
* @throws Exception
*/
public boolean remove(String fileName){
try {
minioClient.removeObject( RemoveObjectArgs.builder().bucket(prop.getBucketName()).object(fileName).build());
}catch (Exception e){
return false;
}
return true;
}
}
5、使用minIO进行文件上传代码示例
@Slf4j
@RestController
@RequestMapping(value = "demo/file")
public class FileController {
@Autowired
private MinioUtil minioUtil;
@Autowired
private MinioConfig prop;
@ApiOperation(value = "查看存储bucket是否存在")
@GetMapping("/bucketExists")
public R bucketExists(@RequestParam("bucketName") String bucketName) {
return R.ok().put("bucketName",minioUtil.bucketExists(bucketName));
}
@ApiOperation(value = "创建存储bucket")
@GetMapping("/makeBucket")
public R makeBucket(String bucketName) {
return R.ok().put("bucketName",minioUtil.makeBucket(bucketName));
}
@ApiOperation(value = "删除存储bucket")
@GetMapping("/removeBucket")
public R removeBucket(String bucketName) {
return R.ok().put("bucketName",minioUtil.removeBucket(bucketName));
}
@ApiOperation(value = "获取全部bucket")
@GetMapping("/getAllBuckets")
public R getAllBuckets() {
List<Bucket> allBuckets = minioUtil.getAllBuckets();
return R.ok().put("allBuckets",allBuckets);
}
@ApiOperation(value = "文件上传返回url")
@PostMapping("/upload")
public R upload(@RequestParam("file") MultipartFile file) {
String objectName = minioUtil.upload(file);
if (null != objectName) {
return R.ok().put("url",(prop.getEndpoint() + "/" + prop.getBucketName() +
"/" + objectName));
}
return R.error();
}
@ApiOperation(value = "图片/视频预览")
@GetMapping("/preview")
public R preview(@RequestParam("fileName") String fileName) {
return R.ok().put("filleName",minioUtil.preview(fileName));
}
@ApiOperation(value = "文件下载")
@GetMapping("/download")
public R download(@RequestParam("fileName") String fileName, HttpServletResponse res)
{
minioUtil.download(fileName,res);
return R.ok();
}
@ApiOperation(value = "删除文件", notes = "根据url地址删除文件")
@PostMapping("/delete")
public R remove(String url) {
String objName = url.substring(url.lastIndexOf(prop.getBucketName()+"/") +
prop.getBucketName().length()+1);
minioUtil.remove(objName);
return R.ok().put("objName",objName);
}
}
参考博客:
SpringBoot整合MinIO 「看这一篇就够了」_spring boot_兔老大-RabbitBoss-GitCode 开源社区