最近在学习,在SpringBoot上进行分片上传、断点续传、直接上传到Minio服务器上,中间也遇到的不少坑、自定义minio继承MinioClient来实现分片上传、比较适合初学者。
一、大致的流程如下:
- 前端获取文件MD5,发送至后台判断是否有该文件,有则直接转存;
- 前端调用初始化接口,后端调用 minio 初始化,返回分片上传地址和 uploadId;
- 前端上传分片文件;
- 上传完成后,前端发送请求至后台服务,后台服务调用 minio 合并文件;
前端代码地址:https://github.com/lanweihong/vue-minio-upload-sample
流程图如下:
二、实现过程
2.1、获取 minio 依赖
我这里使用的Gradle管理的项目:
// minio
implementation 'io.minio:minio:8.2.1'
如果用maven管理项目可以访问官网:
2.2、配置minio yml文件
application.yml配置如下:
minio:
endpoint: ${MINIO_ENDPOINT:https://play.minio.io:9000}
access: ${MINIO_ASSESSKEY:Q3AM3UQ867SPQQA43P2F}
secre: ${MINIO_SECRETKEY:zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG}
bucket: ${MINIO_BUCKET:tuinetest}
2.3、获取minio默认属性
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {
/**
* 文件服务地址
*/
private String endpoint;
/**
* 文件服务器账号
*/
private String access;
/**
* 文件服务认证信息
*/
private String secre;
/**
* 桶存储名称
*/
private String bucket;
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getAccess() {
return accesskey;
}
public void setAccess(String access) {
this.access = access;
}
public String getSecre() {
return secre;
}
public void setSecret(String secre) {
this.secre = secre;
}
public String getBucket() {
return bucket;
}
public void setBucket(String bucket) {
this.bucket = bucket;
}
@Override
public String toString() {
return "MinioProperties{" +
"endpoint='" + endpoint + '\'' +
", access='" + access + '\'' +
", secre='" + secre + '\'' +
", bucket='" + bucket + '\'' +
'}';
}
}
2.4、自定义Minio继承 MinioClient
2.4.1、如果我们不继承MinioClient 访问 listParts 查询分片信息是会报错的、通过继承 MinioClient 来去实现这个方法就可以了。
2.4.2、方法上参数写着注解说明、这个参数是用到了、没写则是没有用到,直接传NULL即可。
@Component
public class CustomMinioClient extends MinioClient {
public CustomMinioClient(MinioClient client) {
super(client);
}
/**
* 初始化分片上传、获取 uploadId
*
* @param bucket String 存储桶名称
* @param region String
* @param object String 文件名称
* @param headers Multimap<String, String> 请求头
* @param extraQueryParams Multimap<String, String>
* @return String
*/
public String initMultiPartUpload(String bucket, String region, String object, Multimap<String, String> headers, Multimap<String, String> extraQueryParams) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, ServerException, InternalException, XmlParserException, InvalidResponseException, ErrorResponseException {
CreateMultipartUploadResponse response = this.createMultipartUpload(bucket, region, object, headers, extraQueryParams);
return response.result().uploadId();
}
/**
* 合并分片
*
* @param bucketName String 桶名称
* @param region String
* @param objectName String 文件名称
* @param uploadId String 上传的 uploadId
* @param parts Part[] 分片集合
* @param extraHeaders Multim