什么是minio
引用官网:
MinIO是根据GNU Affero通用公共许可证v3.0发布的高性能对象存储。它与Amazon S3云存储服务兼容。使用MinIO构建用于机器学习,分析和应用程序数据工作负载的高性能基础架构。
官网地址:
https://min.io/
文档地址:
https://docs.min.io/
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
一. 使用docker 搭建minio 服务。
GNU / Linux和macOS
dockerrun-p9000:9000
--nameminio1
-v/mnt/data:/data
-e"MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE"
-e"MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
minio/minioserver/data
windows
dockerrun-p9000:9000
--nameminio1
-vD:data:/data
-e"MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE"
-e"MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
minio/minioserver/data
-
MINIO_ROOT_USER
:为用户key -
MINIO_ROOT_PASSWORD
:为用户密钥
以上搭建的都是单机版的。想要了解分布式 的方式请查看官网文档。
这就是在win的docker上运行的。
当启动后在浏览器访问http://localhost:9000
就可以访问minio的图形化界面了,如图所示:
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
二. 下面开始搭建springboot 环境
初始化一个springboot项目大家都会,这里不多做介绍。
主要是介绍需要引入的依赖:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
<groupId>io.miniogroupId>
<artifactId>minioartifactId>
<version>8.2.1version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
依赖可以官方文档里找:https://docs.min.io/docs/java-client-quickstart-guide.html
下面介绍配置文件:
spring:
servlet:
multipart:
max-file-size:10MB
max-request-size:10MB
#minio配置
minio:
access-key:AKIAIOSFODNN7EXAMPLE#key就是docker初始化是设置的,密钥相同
secret-key:wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
url:http://localhost:9000
bucket-name:wdhcr
thymeleaf:
cache:false
创建minio的配置类:
@Configuration
@ConfigurationProperties(prefix="spring.minio")
@Data
publicclassMinioConfiguration{
privateStringaccessKey;
privateStringsecretKey;
privateStringurl;
privateStringbucketName;
@Bean
publicMinioClientminioClient(){
returnMinioClient.builder()
.endpoint(url)
.credentials(accessKey,secretKey)
.build();
}
}
使用配置属性绑定进行参数绑定,并初始化一个minio client对象放入容器中。
下面就是我封装的minio client 操作minio的简单方法的组件。
@Component
publicclassMinioComp{
@Autowired
privateMinioClientminioClient;
@Autowired
privateMinioConfigurationconfiguration;
/**
*@description:获取上传临时签名
*@dateTime:2021/5/1314:12
*/
publicMapgetPolicy(StringfileName,ZonedDateTimetime){
PostPolicypostPolicy=newPostPolicy(configuration.getBucketName(),time);
postPolicy.addEqualsCondition("key",fileName);
try{
Mapmap=minioClient.getPresignedPostFormData(postPolicy);
HashMapmap1=newHashMap<>();
map.forEach((k,v)->{
map1.put(k.replaceAll("-",""),v);
});
map1.put("host",configuration.getUrl()+"/"+configuration.getBucketName());
returnmap1;
}catch(ErrorResponseExceptione){
e.printStackTrace();
}catch(InsufficientDataExceptione){
e.printStackTrace();
}catch(InternalExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(InvalidResponseExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(ServerExceptione){
e.printStackTrace();
}catch(XmlParserExceptione){
e.printStackTrace();
}
returnnull;
}
/**
*@description:获取上传文件的url
*@dateTime:2021/5/1314:15
*/
publicStringgetPolicyUrl(StringobjectName,Methodmethod,inttime,TimeUnittimeUnit){
try{
returnminioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(method)
.bucket(configuration.getBucketName())
.object(objectName)
.expiry(time,timeUnit).build());
}catch(ErrorResponseExceptione){
e.printStackTrace();
}catch(InsufficientDataExceptione){
e.printStackTrace();
}catch(InternalExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(InvalidResponseExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(XmlParserExceptione){
e.printStackTrace();
}catch(ServerExceptione){
e.printStackTrace();
}
returnnull;
}
/**
*@description:上传文件
*@dateTime:2021/5/1314:17
*/
publicvoidupload(MultipartFilefile,StringfileName){
//使用putObject上传一个文件到存储桶中。
try{
InputStreaminputStream=file.getInputStream();
minioClient.putObject(PutObjectArgs.builder()
.bucket(configuration.getBucketName())
.object(fileName)
.stream(inputStream,file.getSize(),-1)
.contentType(file.getContentType())
.build());
}catch(ErrorResponseExceptione){
e.printStackTrace();
}catch(InsufficientDataExceptione){
e.printStackTrace();
}catch(InternalExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(InvalidResponseExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(ServerExceptione){
e.printStackTrace();
}catch(XmlParserExceptione){
e.printStackTrace();
}
}
/**
*@description:根据filename获取文件访问地址
*@dateTime:2021/5/1711:28
*/
publicStringgetUrl(StringobjectName,inttime,TimeUnittimeUnit){
Stringurl=null;
try{
url=minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(configuration.getBucketName())
.object(objectName)
.expiry(time,timeUnit).build());
}catch(ErrorResponseExceptione){
e.printStackTrace();
}catch(InsufficientDataExceptione){
e.printStackTrace();
}catch(InternalExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(InvalidResponseExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(XmlParserExceptione){
e.printStackTrace();
}catch(ServerExceptione){
e.printStackTrace();
}
returnurl;
}
}
简单说明:
- 使用MultipartFile接收前端文件流,再上传到minio。
- 构建一个formData的签名数据,给前端,让前端之前上传到minio。
- 构建一个可以上传的临时URL给前端,前端通过携带文件请求该URL进行上传。
- 使用filename请求服务端获取临时访问文件的URL。(最长时间为7 天,想要永久性访问,需要其他设置,这里不做说明。)
下面展示页面html,使用的是VUE+element-ui进行渲染。
html>
<html>
<head>
<metacharset="UTF-8">
<linkrel="stylesheet"href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<title>上传图片title>
head>
<body>
<divid="app">
<el-row:gutter="2">
<el-col:span="8">
<divclass="div-center-class">
<divclass="">
<center><h3>传统上传h3>center>
<el-upload
class="upload-demo"
action="#"
drag
:http-request="uploadHandle">
<iclass="el-icon-upload">i>
<divclass="el-upload__text">将文件拖到此处,或<em>点击上传em>div>
<divclass="el-upload__tip"slot="tip">只能上传jpg/png文件,且不超过500kbdiv>
el-upload>
<divv-if="imgUrl">
<img:src="imgUrl"style="width:40px;height:40px">img>
div>
div>
div>
el-col>
<el-col:span="8">
<divclass="div-center-class">
<divclass="">
<center><h3>前端formData直传h3>center>
<el-upload
class="upload-demo"
action="#"
drag
:http-request="httpRequestHandle">
<iclass="el-icon-upload">i>
<divclass="el-upload__text">将文件拖到此处,或<em>点击上传em>div>
<divclass="el-upload__tip"slot="tip">只能上传jpg/png文件,且不超过500kbdiv>
el-upload>
<divv-if="directUrl">
<img:src="directUrl"style="width:40px;height:40px">img>
div>
div>
div>
el-col>
<el-col:span="8">
<divclass="div-center-class">
<divclass="">
<center><h3>前端Url直传h3>center>
<el-upload
class="upload-demo"
action="#"
drag
:http-request="UrlUploadHandle">
<iclass="el-icon-upload">i>
<divclass="el-upload__text">将文件拖到此处,或<em>点击上传em>div>
<divclass="el-upload__tip"slot="tip">只能上传jpg/png文件,且不超过500kbdiv>
el-upload>
<divv-if="uploadUrl">
<img:src="uploadUrl"style="width:40px;height:40px">img>
div>
div>
div>
el-col>
el-row>
div>
body>
<scriptsrc="https://unpkg.com/vue/dist/vue.js">script>
<scriptsrc="https://unpkg.com/element-ui/lib/index.js">script>
<scriptsrc="https://unpkg.com/axios/dist/axios.min.js">script>
<script>
newVue({
el:'#app',
data:function(){
return{
imgUrl:'',
directUrl:'',
uploadUrl:''
}
},
methods:{
uploadHandle(options){
let{file}=options;
this.traditionPost(file);
},
traditionPost(file){
_that=this
constform=newFormData();
form.append("fileName",file.name);
form.append("file",file);
this.axiosPost("post","/upload",form).then(function(res){
if(res.status===200){
_that.imgUrl=res.data.data
}else{
alert("上传失败!")
}
})
},
getpolicy(file){
_that=this
axios.get('policy?fileName='+file.name)
.then(function(response){
let{xamzalgorithm,xamzcredential,policy,xamzsignature,xamzdate,host}=response.data.data;
letformData=newFormData();
formData.append("key",file.name);
formData.append("x-amz-algorithm",xamzalgorithm);//让服务端返回200,不设置则默认返回204。
formData.append("x-amz-credential",xamzcredential);
formData.append("policy",policy);
formData.append("x-amz-signature",xamzsignature);
formData.append("x-amz-date",xamzdate);
formData.append("file",file);
//发送POST请求
_that.axiosPost("post",host,formData).then(function(res){
if(res.status===204){
axios.get('url?fileName='+file.name).then(function(res){
_that.directUrl=res.data.data;
})
}else{
alert("上传失败!")
}
})
})
},
httpRequestHandle(options){
let{file}=options;
this.getpolicy(file);
},
UrlUploadHandle(options){
let{file}=options;
this.getUploadUrl(file);
},
getUploadUrl(file){
_that=this
console.log(file)
axios.get('uploadUrl?fileName='+file.name)
.then(function(response){
leturl=response.data.data;
//发送put请求
letconfig={'Content-Type':file.type}
_that.axiosPost("put",url,file,config).then(function(res){
if(res.status===200){
axios.get('url?fileName='+file.name).then(function(res){
_that.uploadUrl=res.data.data;
})
}else{
alert("上传失败!")
}
})
})
},
//封装
//axios封装post请求
axiosPost(method,url,data,config){
letresult=axios({
method:method,
url:url,
data:data,
headers:config
}).then(resp=>{
returnresp
}).catch(error=>{
return"exception="+error;
});
returnresult;
}
}
})
script>
<style>
.div-center-class{
padding:28%0%;
text-align:center;
background:beige;
}
style>
html>
可以分别体验不同的实现效果。
以上就是使用springboot搭建基于minio的高性能存储服务的全部步骤了。
项目地址是:
https://gitee.com/jack_whh/minio-upload
审核编辑 :李倩
-
云存储
+关注
关注
7文章
737浏览量
46044 -
机器学习
+关注
关注
66文章
8408浏览量
132575 -
Docker
+关注
关注
0文章
457浏览量
11849
原文标题:Spring Boot + minio 实现高性能存储服务,So Easy~!
文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论