一、MinIO的下载安装以及基本使用
1.下载地址:https://dl.min.io/server/minio/release/windows-amd64/minio.exe
2.下载好后需要手动创建【data】文件夹用于存储Minio中的数据
3.在对应文件路径处,键入【cmd】 后设置MinIO的一些变量(第一次启动需要配置)****
set MINIO_ROOT_USER=admin
set MINIO_ROOT_PASSWORD=admin123
set MINIO_ACCESS_KEY=admin
set MINIO_SECRET_KEY=admin123
5.下面是我踩的坑,如果只设置了MINIO_ROOT_USER和MINIO_ROOT_PASSWORD的值,而不设置MINIO_ACCESS_KEY和MINIO_SECRET_KEY的值,当启动minio服务的时候就会报以下异常:
6. 启动minio服务
minio.exe server data
7.进入登录页面后,输入对应的用户名和密码,也就是之前设置的MINIO_ROOT_USER和MINIO_ROOT_PASSWORD的值。
8. 进入主界面后,点击左侧导航栏中的Buckets,然后点击Create Bucket。
9.进入该桶,点击upload,上传一个文件
10.点击左侧导航栏中的Buckets,进入该桶,修改权限为public,这样外界就可以访问上传的文件了。
桶的默认权限是private,所以外界访问不到,需要修改访问权限为public,但是要注意安全问题
二. SpringBoot集成MinIO
1.引入依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.0.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
2.编写配置文件
server:
port: 8080
spring:
# 配置文件上传大小限制
servlet:
multipart:
max-file-size: 200MB
max-request-size: 200MB
minio:
host: http://127.0.0.1:9000 # 访问地址
url: ${minio.host}/${minio.bucket}/ # 对象存储服务的url
access-key: minioadmin # 登录账号
secret-key: minioadmin # 登录账号密码
bucketName: test-bucket # 文件桶的名称
bucket: public // 权限
3.编写minio配置类
@Configuration
public class MinIoClientConfig {
/**
* minio配置
*/
@Value("${minio.url}")
private String endpoint;
@Value("${minio.accessKey}")
private String accessKey;
@Value("${minio.secretKey}")
private String secretKey;
@Value("${minio.bucketName}")
private String bucketName;
/**
* 注入minio客户端
*
* @return minio客户端对象
*/
@Bean
public MinioClient minioClient() {
return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
}
}
4.编写minio工具类
@Component
public class MinioUtil {
/**
* minio配置
*/
@Value("${minio.url}")
private String endpoint;
@Autowired
private MinioClient minioClient;
/**
* 创建一个桶
*/
public void createBucket(String bucket) throws Exception {
boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
if (!found) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
}
}
/**
* 上传一个文件
*/
public void uploadFile(InputStream stream, String bucket, String objectName) throws Exception {
ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName)
.stream(stream, -1, 10485760).build());
System.out.println(objectWriteResponse.object() + " is uploaded successfully.");
}
/**
* 列出所有的桶
*/
public List<String> listBuckets() throws Exception {
List<Bucket> list = minioClient.listBuckets();
List<String> names = new ArrayList<>();
list.forEach(b -> {
names.add(b.name());
});
return names;
}
/**
* 列出一个桶中的所有文件和目录
*/
public List<Fileinfo> listFiles(String bucket) throws Exception {
Iterable<Result<Item>> results = minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucket).recursive(true).build());
List<Fileinfo> infos = new ArrayList<>();
results.forEach(r->{
Fileinfo info = new Fileinfo();
try {
Item item = r.get();
info.setFilename(item.objectName());
info.setDirectory(item.isDir());
info.setFilepath(endpoint+"/"+bucket+"/"+item.objectName());
infos.add(info);
} catch (Exception e) {
e.printStackTrace();
}
});
return infos;
}
/**
* 下载一个文件
*/
public InputStream download(String bucket, String objectName) throws Exception {
InputStream stream = minioClient.getObject(
GetObjectArgs.builder().bucket(bucket).object(objectName).build());
return stream;
}
/**
* 删除一个桶
*/
public void deleteBucket(String bucket) throws Exception {
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build());
}
/**
* 删除一个对象
*/
public void deleteObject(String bucket, String objectName) throws Exception {
minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectName).build());
}
/**
* 复制文件
*/
public void copyObject(String sourceBucket, String sourceObject, String targetBucket, String targetObject) throws Exception {
this.createBucket(targetBucket);
minioClient.copyObject(CopyObjectArgs.builder().bucket(targetBucket).object(targetObject)
.source(CopySource.builder().bucket(sourceBucket).object(sourceObject).build()).build());
}
/**
* 获取文件信息
*/
public String getObjectInfo(String bucket, String objectName) throws Exception {
return minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(objectName).build()).toString();
}
/**
* 生成一个给HTTP GET请求用的presigned URL。
* 浏览器/移动端的客户端可以用这个URL进行下载,
* 即使其所在的存储桶是私有的。
*/
public String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) throws Exception {
GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs
.builder().bucket(bucketName).object(objectName).expiry(expires).method(Method.GET).build();
return minioClient.getPresignedObjectUrl(build);
}
/**
* 获取minio中所有的文件
*/
public List<Fileinfo> listAllFile() throws Exception {
List<String> list = this.listBuckets();
List<Fileinfo> fileinfos = new ArrayList<>();
for (String bucketName : list) {
fileinfos.addAll(this.listFiles(bucketName));
}
return fileinfos;
}
}
5.编写文件实体类
@Data
public class Fileinfo {
String filename;
String filepath;
Boolean directory;
}
6.编写接口响应实体
@Data
public class ResultData<T> {
public static final Integer SUCCESS_CODE = 200;
public static final Integer FAIL_CODE = 4000;
public static final String SUCCESS_MESSAGE = "操作成功";
public static final String FAIL_MESSAGE = "操作失败";
/**
* 返回状态码
*/
private Integer code;
/**
* 返回信息
*/
private String message;
/**
* 返回数据
*/
private T data;
public ResultData() {
}
public static <T> ResultData<T> success() {
ResultData<T> resultUtil = new ResultData<>();
resultUtil.setCode(SUCCESS_CODE);
resultUtil.setMessage(SUCCESS_MESSAGE);
return resultUtil;
}
public static <T> ResultData<T> success(T data) {
ResultData<T> resultUtil = success();
resultUtil.setData(data);
return resultUtil;
}
public static <T> ResultData<T> success(String message, T data) {
ResultData<T> resultUtil = success();
resultUtil.setMessage(message);
resultUtil.setData(data);
return resultUtil;
}
public static <T> ResultData<T> success(Integer code, String message, T data) {
ResultData<T> resultUtil = new ResultData<>();
resultUtil.setCode(code);
resultUtil.setMessage(message);
resultUtil.setData(data);
return resultUtil;
}
public static <T> ResultData<T> success(Integer code, String message,Integer count, T data) {
ResultData<T> resultUtil = new ResultData<>();
resultUtil.setCode(code);
resultUtil.setMessage(message);
resultUtil.setData(data);
return resultUtil;
}
public static <T> ResultData<T> fail() {
ResultData<T> resultUtil = new ResultData<>();
resultUtil.setCode(FAIL_CODE);
resultUtil.setMessage(FAIL_MESSAGE);
return resultUtil;
}
public static <T> ResultData<T> fail(T data) {
ResultData<T> resultUtil = fail();
resultUtil.setData(data);
return resultUtil;
}
public static <T> ResultData<T> fail(String message, T data) {
ResultData<T> resultUtil = fail();
resultUtil.setMessage(message);
resultUtil.setData(data);
return resultUtil;
}
public static <T> ResultData<T> fail(Integer code, String message) {
ResultData<T> resultUtil = fail();
resultUtil.setCode(code);
resultUtil.setMessage(message);
return resultUtil;
}
public static <T> ResultData<T> fail(Integer code, String message, T data) {
ResultData<T> resultUtil = new ResultData<>();
resultUtil.setCode(code);
resultUtil.setMessage(message);
resultUtil.setData(data);
return resultUtil;
}
public void setCode(int code){
this.code = code;
}
public int getCode(){
return this.code;
}
public void setMessage(String message){
this.message = message;
}
public String getMessage(){
return message;
}
public void setData(T data){
this.data = data;
}
public T getData(){
return data;
}
}
7.创建minio控制器
/**
* minio相关接口
*
* @author songwp
* @date 2024/11/11 11:28
*/
@RestController
@RequestMapping("minio")
public class MinioController {
@Autowired
MinioUtil minioUtil;
/**
* 文件上传
*
* @param file 文件
* @param bucket 桶名
* @param objectName 对象名
* @return 是否成功
* @throws Exception
*/
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public ResultData upload(@RequestParam MultipartFile file,
@RequestParam String bucket,
@RequestParam(required = false) String objectName) throws Exception {
minioUtil.createBucket(bucket);
if (objectName != null) {
minioUtil.uploadFile(file.getInputStream(), bucket, objectName + "/" + file.getOriginalFilename());
} else {
minioUtil.uploadFile(file.getInputStream(), bucket, file.getOriginalFilename());
}
return ResultData.success();
}
/**
* 获取文件信息
* @param bucket 桶名
* @return 是否成功
*/
@RequestMapping(value = "/getFile", method = RequestMethod.GET)
public ResultData getFile(@RequestParam ("bucket")String bucket){
try {
List<Fileinfo> fileinfos = minioUtil.listFiles(bucket);
return ResultData.success(fileinfos);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 文件下载
*
* @param bucket 桶名
* @param objectName 对象名
* @return 是否成功
*/
@GetMapping("download")
public ResultData download(@RequestParam("bucket") String bucket,
@RequestParam("objectName") String objectName){
try {
InputStream download = minioUtil.download(bucket, objectName);
return ResultData.success();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 获取文件信息
*
* @param bucket 桶名
* @param objectName 对象名
* @return 是否成功
*/
@GetMapping("getObjectInfo")
public ResultData getObjectInfo(@RequestParam("bucket") String bucket,
@RequestParam("objectName") String objectName) throws Exception {
String objectInfo = minioUtil.getObjectInfo(bucket, objectName);
String objectStat = objectInfo.replaceAll("ObjectStat", "");
return ResultData.success(objectStat);
}
/**
* 生成一个给HTTP GET请求用的presigned URL。
*
* @param bucket 桶名
* @param objectName 对象名
* @return 是否成功
*/
@GetMapping("getObjectUrl")
public ResultData getObjectUrl(@RequestParam("bucket") String bucket,
@RequestParam("objectName") String objectName) throws Exception {
String url = minioUtil.getPresignedObjectUrl(bucket, objectName,7200);
return ResultData.success(url);
}
/**
* 列出所有的桶
*/
@RequestMapping(value = "/listBuckets", method = RequestMethod.GET)
public ResultData listBuckets() throws Exception {
return ResultData.success(minioUtil.listBuckets());
}
/**
* 获取minio中所有的文件
*/
@RequestMapping(value = "/listAllFile", method = RequestMethod.GET)
public ResultData listAllFile() throws Exception {
return ResultData.success(minioUtil.listAllFile());
}
}
8.postman接口调用实例
9.最后查看test-bucket桶中是否有刚才上传的文件就可以了。如果有则表明你的项目已经成功集成minio了