小伙伴们好,欢迎关注,一起学习,无限进步
minio 是对象存储服务。它基于 Apache License 开源协议,兼容 Amazon S3 云存储接口。适合存储非结构化数据,如图片,音频,视频,日志等。对象文件最大可以达到 5TB。
优点有高性能,可扩展,操作简单,有图形化操作界面,读写性能优异等。官网
minio 部署可参考这篇:Minio 详细安装部署步骤
SpringBoot 快速整合 minio
1、添加 Maven 依赖
在 pom.xml 文件中添加MinIO客户端依赖项
io.minio
minio
8.2.2
com.alibaba
fastjson
1.2.78
2、配置MinIO连接信息
在 application.properties 或 application.yml 文件中配置MinIO的连接信息,包括服务器地址、端口、凭据等信息
# Minio 配置
minio.endpoint=127.0.0.1:9000 #对象存储服务的URL
minio.accessKey=admin #Access key账户 写账号也可以
minio.secretKey=admin #Secret key密码
minio.bucketName=test # 桶名称
# 过期时间
minio.expire=7200
# Minio 配置
minio:
endpoint: 127.0.0.1:9000 #对象存储服务的URL
accessKey: admin #Access key账户 写账号也可以
secretKey: admin #Secret key密码
bucketName: test # 桶名称
expire: 7200 # 过期时间
3、创建 MinIO 客户端 Bean
在 SpringBoot 应用的配置类中创建一个 MinIO客户端的 Bean,以便在应用中使用 MinIO 服务
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* minio 配置属性
*/
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {
/**
* Minio 连接地址
*/
private String endpoint;
/**
* accessKey 或 账号
*/
private String accessKey;
/**
* secretKey 或 密码
*/
private String secretKey;
/**
* 桶名称
*/
private String bucketName;
/**
* 默认是秒 地址过期时间,设置默认值7200秒
*/
private int expire = 7200;
}
4、异常枚举类
/**
* 异常枚举类
*/
public enum ExceptionEnums {
FILE_NAME_NOT_NULL("0001", "文件名不能为空"),
BUCKET_NAME_NOT_NULL("0002", "桶名称不能为空"),
FILE_NOT_EXIST("0003", "文件不存在"),
BUCKET_NOT_EXIST("0004", "桶不存在"),
BUCKET_NAME_NOT_EXIST("0005", "桶不存在,需要先创建桶在创建文件夹");//枚举类如果写方法的话,此处需要写分号
private String code;
private String msg;
ExceptionEnums(String ecode, String emsg) {
this.code = ecode;
this.msg = emsg;
}
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
public static ExceptionEnums statOf(String code) {
for (ExceptionEnums state : values())
if (state.getCode().equals(code))
return state;
return null;
}
}
5、全局异常
import org.springframework.http.HttpStatus;
/**
* 异常
*/
public class GeneralException extends RuntimeException {
private Integer errorCode;
public GeneralException() {
}
public GeneralException(Throwable throwable) {
super(throwable);
}
public GeneralException(String msg) {
super(msg);
this.errorCode = HttpStatus.INTERNAL_SERVER_ERROR.value();
}
public GeneralException(Integer errorCode, String msg) {
super(msg);
this.errorCode = errorCode;
}
public Integer getErrorCode() {
return this.errorCode;
}
public void setErrorCode(Integer errorCode) {
this.errorCode = errorCode;
}
}
6、minio 工具类
工具类包含创建 bucket,获取全部 bucket,获取 bucket 文件名和大小列表,文件上传,获取上传文件的完整路径,创建文件夹或目录,判断 bucket 是否存在,判断文件是否存在,文件下载,删除文件,批量删除文件方法
import com.alibaba.fastjson.JSON;
import io.minio.*;
import io.minio.errors.*;
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 lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.util.*;
/**
* Minio 工具类
*/
@Component
@Slf4j
public class MinioUtils {
@Autowired
private MinioClient minioClient;
@Autowired
private MinioProperties minioProperties;
/**
* 初始化Bucket
*/
private void createBucket(String bucketName) {
try {
// 判断 BucketName 是否存在
if (bucketExists(bucketName)) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 验证bucketName是否存在
*
* @return boolean true:存在
*/
public boolean bucketExists(String bucketName) {
if (StringUtils.isEmpty(bucketName)) {
throw new GeneralException(ExceptionEnums.BUCKET_NAME_NOT_NULL.getMsg());
}
boolean flag = true;
try {
flag = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
/**
* 获取全部bucket
*
*/
public List getAllBuckets() {
List list = null;
try {
final List buckets = minioClient.listBuckets();
list = new ArrayList<>(buckets.size());
for (Bucket bucket : buckets) {
list.add(bucket.name());
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* 根据bucketName获取信息
*
* @param bucketName bucket名称
* @return
*/
public String getBucket(String bucketName) throws Exception {
final Optional first = minioClient.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
String name = null;
if (first.isPresent()) {
name = first.get().name();
}
return name;
}
/**
* 获取桶中文件名和大小列表
*
* @param bucketName bucket名称
* @param recursive 查询是否递归
* @return
*/
public List
7、文件调用接口
上传文件,获取上传文件完整路径,文件下载,文件删除,批量删除
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
@RestController
public class MinioController {
@Autowired
private MinioUtils minioUtils;
/**
* 获取桶中文件名和大小列表
*
* @return
*/
@GetMapping("/getFileList")
public List getFileList() {
return minioUtils.getFileList("test", true);
}
/**
* 判断文件是否存在
*
* @param bucketName
* @param fileName
* @return
*/
@GetMapping("/doFileNameExist")
public boolean doFileNameExist(String bucketName, String fileName) {
return minioUtils.doFolderExist(bucketName, fileName);
}
/**
* 上传文件
*
* @param file
* @return
*/
@PostMapping("/uploadFiles")
public Map uploadFiles(String bucketName, @RequestParam(name = "file", required = false) MultipartFile[] file) {
if (file == null || file.length == 0) {
throw new GeneralException(ExceptionEnums.FILE_NAME_NOT_NULL.getMsg());
}
if (StringUtils.isEmpty(bucketName)) {
throw new GeneralException(ExceptionEnums.BUCKET_NAME_NOT_NULL.getMsg());
}
return minioUtils.uploadFile(bucketName, file);
}
/**
* 获取上传文件的完整浏览路径
*
* @param filename
* @return
*/
@GetMapping("/getPresignedObjectUrl")
public String getPresignedObjectUrl(@RequestParam(name = "filename") String filename) {
return minioUtils.getPresignedObjectUrl("test", filename, null);
}
/**
* 文件下载
*
* @param response
* @param fileName
*/
@GetMapping("/downloadFile")
public void downloadFile(HttpServletResponse response, @RequestParam("fileName") String fileName) {
minioUtils.downloadFile(response, "test", fileName);
}
/**
* 删除单个文件
*
* @param fileName 完整路径(不包含bucket)
*/
@DeleteMapping("/deleteFile")
public void deleteFile(String bucketName, String fileName) {
minioUtils.deleteFile(bucketName, fileName);
}
/**
* 批量删除文件
*
* @param fileNames 完整路径(不包含bucket)
*/
@DeleteMapping("/deleteBatchFile")
public void deleteBatchFile(String bucketName, @RequestParam("fileNames") List fileNames) {
minioUtils.deleteBatchFile(bucketName, fileNames);
}
}