springboot集成minio客户端
文章目录
- springboot集成minio客户端
- 1 配置文件桶权限
- 2 引入minio客户端依赖
- 3 配置文件修改
- 4 定义minio配置类
- 5 封装MinioClient
- 6 HTTP接口实例
- 7 总结
由于项目技术栈需要使用springboot框架,以下详细介绍spring boot如何集成minio客户端过程,使用intellij idea集成开发环境,maven进行项目管理。
1 配置文件桶权限
首先我们需要部署minio服务并运行
通过minio服务自带的web界面,创建文件桶test:
配置文件桶test权限:
test权限配置成公开可读写权限,便于后续演示操作,如想使用minio权限功能,可参照官方文档。
2 引入minio客户端依赖
在pom.xml中加入minio依赖:
<!--minioclient-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.0.2</version>
</dependency>
3 配置文件修改
在配置文件中增加minio相关配置,我的项目中配置文件格式为properties格式,在末尾增加:
#minio配置参数
minio.endpoint=10.45.154.179
minio.port=9000
minio.accessKey=minioadmin
minio.secretKey=minioadmin
minio.bucketName=test
endpoint、port改成自己minio服务器的IP和端口,accessKey/secretKey改成自己minio服务器的账号信息即可。
4 定义minio配置类
minio参数配置类定义如下,自动映射properties对应参数项,为对象bean属性捆绑数据,类名为MinioConfig。
package com.znv.manage.minio;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
//minio服务Ip地址
private String endpoint;
//minio服务端口
private int port;
//minio接入用户名
private String accessKey;
//minio接入密码
private String secretKey;
//通讯方式是否为https
//private boolean secure;
//存储桶名
private String bucketName;
}
5 封装MinioClient
为了便于业务层调用,增加代码的灵活性和扩展性,对原始的MinioClient进行封装,形成minio操作的工具类,代码如下:
package com.znv.manage.minio;
import com.alibaba.cloud.commons.io.IOUtils;
import io.minio.MinioClient;
import io.minio.ObjectStat;
import io.minio.PutObjectOptions;
import io.minio.messages.Bucket;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;
@Slf4j
@Component
public class MinIoUtil {
@Autowired
MinioConfig minioConfig;
private static MinioClient minioClient;
/**
* 初始化minio配置
*
* @param :
* @return: void
* @date :
*/
@PostConstruct
public void init() {
try {
minioClient = new MinioClient(minioConfig.getEndpoint(), minioConfig.getPort(), minioConfig.getAccessKey(), minioConfig.getSecretKey(), false);
} catch (Exception e) {
e.printStackTrace();
log.error("minioncliet init error: ", e.fillInStackTrace());
}
}
/**
* 判断 bucket是否存在
*
* @param bucketName: 文件桶名
* @return: boolean
* @date :
*/
@SneakyThrows(Exception.class)
public static boolean bucketExists(String bucketName) {
return minioClient.bucketExists(bucketName);
}
/**
* 创建 bucket
*
* @param bucketName: 文件桶名
* @return: void
* @date :
*/
@SneakyThrows(Exception.class)
public static void createBucket(String bucketName) {
boolean isExist = minioClient.bucketExists(bucketName);
if (!isExist) {
minioClient.makeBucket(bucketName);
}
}
/**
* 获取全部bucket
*
* @param :
* @return: java.util.List<io.minio.messages.Bucket>
* @date :
*/
@SneakyThrows(Exception.class)
public static List<Bucket> getAllBuckets() {
return minioClient.listBuckets();
}
/**
* 文件上传
*
* @param bucketName: 文件桶名
* @param fileName: 文件名
* @param filePath: 文件路径
* @return: void
* @date :
*/
@SneakyThrows(Exception.class)
public static void upload(String bucketName, String fileName, String filePath) {
minioClient.putObject(bucketName, fileName, filePath, null);
}
/**
* 文件上传
*
* @param bucketName: 文件桶名
* @param fileName: 文件名
* @param stream: 文件流
* @return: java.lang.String : 文件url地址
* @date :
*/
@SneakyThrows(Exception.class)
public static String upload(String bucketName, String fileName, InputStream stream) {
minioClient.putObject(bucketName, fileName, stream, new PutObjectOptions(stream.available(), -1));
return getFileUrl(bucketName, fileName);
}
/**
* 文件上传
*
* @param bucketName: 文件桶名
* @param file: 文件
* @return: java.lang.String : 文件url地址
* @date :
*/
@SneakyThrows(Exception.class)
public static String upload(String bucketName, MultipartFile file) {
final InputStream is = file.getInputStream();
final String fileName = file.getOriginalFilename();
minioClient.putObject(bucketName, fileName, is, new PutObjectOptions(is.available(), -1));
is.close();
return getFileUrl(bucketName, fileName);
}
/**
* 删除文件
*
* @param bucketName: 文件桶名
* @param fileName: 文件名
* @return: void
* @date :
*/
@SneakyThrows(Exception.class)
public static void deleteFile(String bucketName, String fileName) {
minioClient.removeObject(bucketName, fileName);
}
/**
* 获取minio文件的下载地址
*
* @param bucketName: 文件桶名
* @param fileName: 文件名
* @return: java.lang.String
* @date :
*/
@SneakyThrows(Exception.class)
public static String getFileUrl(String bucketName, String fileName) {
return minioClient.presignedGetObject(bucketName, fileName);
}
/**
* 下载文件
*
* @param bucketName: 文件桶名
* @param fileName: 文件名
* @param
* @return: void
* @date :
*/
@SneakyThrows(Exception.class)
public static InputStream download(String bucketName, String fileName) {
// 获取对象的元数据
return minioClient.getObject(bucketName, fileName);
}
}
6 HTTP接口实例
通过HTTP提供文件上传、下载、删除服务,这里以文件上传为例,实例代码如下:
package com.znv.manage.controller;
import com.alibaba.fastjson.JSONObject;
import com.znv.manage.common.bean.Result;
import com.znv.manage.common.exception.ResultCodeEnum;
import com.znv.manage.minio.MinIoUtil;
import com.znv.manage.minio.MinioConfig;
import com.znv.manage.minio.StorageFileInfo;
import com.znv.manage.service.StorageFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Base64Utils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author wangdenuan
* @version 1.0
* @description: TODO
* @date 2022-4-18 8:47
*/
@Slf4j
@RestController
public class testController {
@Autowired
MinioConfig minioConfig;
@Autowired
StorageFileService storageFileService;
/**
* minio上传文件,文件base64加密
*/
@PostMapping(value = "/test-upload-encryption")
public Object uploadFileEncryption(@RequestBody JSONObject jsonObj) throws IOException {
Result ret = new Result();
if (CollectionUtils.isEmpty(jsonObj)) {
ret.setCode(ResultCodeEnum.SYSTEMERROR.getCode());
ret.setMessage("jsonObj is null");
return ret;
}
String fileData = jsonObj.getString("fileData");
if ((null == fileData) || (0 >= fileData.length())) {
ret.setCode(ResultCodeEnum.NOTACCEPTABLE.getCode());
ret.setMessage("fileData is null");
return ret;
}
byte[] picStream = Base64Utils.decodeFromString(fileData);
String fileName = jsonObj.getString("fileName");
String httpUrl = MinIoUtil.upload(minioConfig.getBucketName(), fileName, new ByteArrayInputStream(picStream));
String filePath = "/LOCATEIMG/" + minioConfig.getBucketName() + "/" + fileName;
JSONObject result = new JSONObject();
result.put("result", "success");
result.put("filePath", filePath);
String[] splitstr = httpUrl.split("\\?", 2);
httpUrl = splitstr[0];
result.put("httpUrl", httpUrl);
return result;
}
}
通过HTTP接口/test-upload-encryption,上传图片base64编码数据,保存到minio存储服务上,并返回图片URL,通过图片URL可直接方案图片(这里配置的权限是公开可读写,所以直接通过urliuke访问)。
通过postman来验证端口,验证过程如下:
可以通过http://10.45.156.156:9000/test/test3.jpg 图片地址直接下载图片:
7 总结
springboot集成minio非常简单,通过封装minioclient,可增加代码的灵活性可扩展性,隔离底层存储接口,后续入要更换其他的存储,经过简单的适配即可实现,通过REST提供存储的基础能力接口,可非常简单的被使用。