前言
大家好,我是作曲家种太阳
上一章节我们介绍了常用中间件的开发,相信你对中间件又有新的了解
资源文件的上传和下载的管理,在服务端是必须的功能,我们这一节开发一个上传用户头像的接口开发,来讲文件管理基本功能~
1. minio的介绍
对象存储系统,类似于阿里oss
特点:
1.高性能
2.可扩展性
3.云的原生支持
4.开放全部源代码 + 企业级支持
5.与Amazon S3 兼容
6. 非常简单易用
minio官网
关系图:
1. 前期准备工作
之前的文章我们讲述很多次怎么配置路由和yaml配置文件的设置与读取,这篇不在手摸手教这些,更关本篇功能实现上,所以你要准备前期工作:
- 编写上传文件的路由,并写controller的函数
- 配置yaml中minio的struct字段(config/config.go),参考
minio:
endpoint: "127.0.0.1:9000"
accessKeyID: "minioadmin"
secretAccessKey: "minioadmin"
复制代码
3.安装minio
官网安装文档,推荐docker安装:docs.minio.org.cn/docs/
4.尝试登陆minio的界面:
http://127.0.0.1:9000/
2. 编写minio初始化链接
(1).在 initialize/minio中
package initialize
import (
"github.com/minio/minio-go"
_ "github.com/minio/minio-go/pkg/encrypt"
"go_gin/global"
"go_gin/utils"
"log"
)
func InitMinIO() {
minioInfo := global.Settings.MinioInfo
// 初使化 minio client对象。false是关闭https证书校验
minioClient, err := minio.New(minioInfo.Endpoint, minioInfo.AccessKeyID, minioInfo.SecretAccessKey, false )
if err != nil {
log.Fatalln(err)
}
//客户端注册到全局变量中
global.MinioClient = minioClient
//创建一个叫userheader的存储桶。
utils.CreateMinoBuket("userheader")
}
复制代码
ps: utils.CreateMinoBuket()还未编写,先注释掉,后面写好再打开 \
(2). 添加global.MinioClient \
在global.globalVar中
MinioClient *minio.Client
复制代码
(3). 在main.go中调用
// 7. 初始化minIO
initialize.InitMinIO()
复制代码
3. 编写minio的操作函数
在utils/minio.go中编写
package utils
import (
"fmt"
"github.com/minio/minio-go"
"github.com/minio/minio-go/v6/pkg/policy"
"go.uber.org/zap"
"go_gin/global"
"io"
"net/url"
"time"
)
// CreateMinoBuket 创建minio 桶
func CreateMinoBuket(bucketName string) {
location := "us-east-1"
err := global.MinioClient.MakeBucket(bucketName, location)
if err != nil {
// 检查存储桶是否已经存在。
exists, err := global.MinioClient.BucketExists(bucketName)
fmt.Println(exists)
if err == nil && exists {
fmt.Printf("We already own %s\n", bucketName)
} else {
fmt.Println(err, exists)
return
}
}
//
err = global.MinioClient.SetBucketPolicy(bucketName, policy.BucketPolicyReadWrite)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("Successfully created %s\n", bucketName)
}
// UploadFile 上传文件给minio指定的桶中
func UploadFile(bucketName, objectName string, reader io.Reader, objectSize int64) (ok bool) {
n, err := global.MinioClient.PutObject(bucketName, objectName, reader, objectSize, minio.PutObjectOptions{ContentType: "application/octet-stream"})
if err != nil {
fmt.Println(err)
return false
}
fmt.Println("Successfully uploaded bytes: ", n)
return true
}
// GetFileUrl 获取文件url
func GetFileUrl(bucketName string, fileName string, expires time.Duration) string {
//time.Second*24*60*60
reqParams := make(url.Values)
presignedURL, err := global.MinioClient.PresignedGetObject(bucketName, fileName, expires, reqParams)
if err != nil {
zap.L().Error(err.Error())
return ""
}
return fmt.Sprintf("%s", presignedURL)
}
复制代码
ps: 这里写了三个函数:
1.CreateMinoBuket 在minio创建桶
2. UploadFile 上传文件
3. GetFileUrl 获取到下载文件的url
4.编写上传头像的接口
在 controller/user.go中
// PutHeaderImage 上传用户头像
func PutHeaderImage(c *gin.Context) {
file, _ := c.FormFile("file")
fileObj, err := file.Open()
if err != nil {
fmt.Println(err)
return
}
// 把文件上传到minio对应的桶中
ok := utils.UploadFile("userheader", file.Filename, fileObj, file.Size)
if !ok {
Response.Err(c, 401, 401, "头像上传失败", "")
return
}
headerUrl := utils.GetFileUrl("userheader", file.Filename, time.Second*24*60*60)
if headerUrl == "" {
Response.Success(c, 400, "获取用户头像失败", "headerMap")
return
}
//TODO 把用户的头像地址存入到对应user表中head_url 中
Response.Success(c, 200, "头像上传成功", map[string]interface{}{
"userheaderUrl": headerUrl,
})
}
复制代码
可以完善的地方:
- 当获取到头像的url,应该把地址存入mysql当中
- 文件名加上uuid防止覆盖(看具有需求)
ps:别忘记给container加入路由!
最后-验证结果环节
(1).在postman请求上传文件路由:
使用userheaderUrl的值在浏览器上请求,文件成功下载
(2).在minio中查看:
http://127.0.0.1:9000/
minio成功添加了上传文件
如果这系列的文章对你有有用,请点赞和留言吧~
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END