背景:
要实现图片上传功能,图片 保存在项目下的一个文件夹,然后 访问的时候 通过 url 访问, 就像以前做的 新手任务的python项目那样,只不过这次使用 golang, 项目是用 gin 框架 。
实现思路
通过表单 上传图片, 将图片保存到项目路径下的文件,图片名字 是随机生成的, 上传成功后,返回 上传的图片名字, 其他的接口 同时将图片的名字 保存到 相应的 数据库字段中。方便使用的时候 通过图片名字 获取项目路径下的图片。
遇到的问题:
图片上传了,但是通过 地址访问的时候,找不到路径,换linux 机器测试也是一样的。
http://127.0.0.1:8080/images/3750556942209024.png
解决办法:
在注册路由的时候 添加 静态文件路径 就可以了。
r.StaticFS(setting.Conf.ImagesDir, http.Dir(setting.Conf.ImagesDir))
路径配置在 config.yaml 文件中, 也可以写死,
r.StaticFS("/images", http.Dir("./images"))
//images 为项目路径下 创建的文件夹。
上传图片的逻辑实现如下:
func MultipartUpload(c *gin.Context) {
// 支持多张图片的上传 form, err := c.MultipartForm() if err != nil { zap.L().Error("MultipartUpload para err:", zap.Error(err)) base.ResponseError(c, base.CodeInvalidContentType) return }
files, ok := form.File["files"]
// 判断key 是否存在 不存在 返回异常。 if !ok { zap.L().Error("MultipartUpload para err", zap.Error(err)) base.ResponseError(c, base.CodeForkKeyLost) return } var images []string var imagesstr string // 遍历 数组进行处理 for _, file := range files { zap.L().Info(file.Filename) //imagesDir := "images" imagesDir := setting.Conf.ImagesDir // 修改成了从配置读取图片文件夹路径。 其实和 写死 一样的。 imagesDir, _ = filepath.Abs(imagesDir) if _, err := os.Stat(imagesDir); os.IsNotExist(err) { if err := os.Mkdir(imagesDir, 0755); err != nil { panic(err) } } idstr := strconv.FormatInt(snowflake.GenID(), 10) imName := idstr + ".png" imageName := path.Join(imagesDir, imName) if err := c.SaveUploadedFile(file, imageName); err != nil { zap.L().Error("Upload err:", zap.Error(err)) base.ResponseError(c, base.CodeServerBusy) return }
// 通过切片 返回上传 了的 图片名字列表
images = append(images, imName) imagesstr += imName + "," } base.ResponseSuccess(c, images) }