当前位置:网站首页>GIN文件上传与返回
GIN文件上传与返回
2022-08-09 12:44:00 【一叶知秋@qqy】
前言
感谢开源项目gin-vue-admin,以及1010工作室的教程,项目文档
我只是在跟着学习,然后记录下笔记而已,可能会有新的代码加入,但是本质还是跟着学习的一个过程。
上传文件
使用postman模拟上传文件
无论使用postman还是前端的同学直接上传文件,都需要在请求头中使用Content-Type来告知,即带值multipart/form-data来进行上传文件
form-data传参
此时在post请求里已经不能传json了,要使用form-data。
此时在postman中的请求参数体,Body中新建一个key,名为file(可以任意一个key),然后将其文件格式设置为File,这时使用的文件格式,换成字符串Text也是允许的。
如果选择的是Text,在后面的Value中直接填写字符串就可以,这里选则的是File,所以在后面Value的位置,点击就可以选择文件,进行模拟传文件的操作。
随便选择一个文本文件查看效果使用
点击打开
在goland中敲入以下代码并运行:
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default() //启动gin路由,携带基础中间件启动 logger and recovery (crash-free) 中间件
r.POST("testUpload", func(c *gin.Context) {
file, _ := c.FormFile("file")
c.JSON(200, gin.H{
"msg":file,
})
})
r.Run(":1010") // listen and serve on 0.0.0.0:8080
}
发起postman的请求:
可以看出,虽然返回的东西并不能看懂,但是已经成功返回了
保存文件
在goland中的返回JSON前添加以下语句,实现接收文件的存储,这里是将接收的文件保存在当前路径下,并使用上传时相同的文件名。
func main() {
r := gin.Default() //启动gin路由,携带基础中间件启动 logger and recovery (crash-free) 中间件
r.POST("testUpload", func(c *gin.Context) {
file, _ := c.FormFile("file")
c.SaveUploadedFile(file, "./"+file.Filename)
c.JSON(200, gin.H{
"msg":file,
})
})
r.Run(":1010") // listen and serve on 0.0.0.0:8080
}
然后使用postman再次发起一个上传文件请求,
已经将文件保存下来,并经过对比与上传的文件无异
此处给出gin框架SaveUploadedFile实现的源码
// SaveUploadedFile uploads the form file to specific dst.
func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error {
src, err := file.Open()
if err != nil {
return err
}
defer src.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, src)
return err
}
然后将这个部分使用自己的方式进行实现
func main() {
r := gin.Default() //启动gin路由,携带基础中间件启动 logger and recovery (crash-free) 中间件
r.POST("testUpload", func(c *gin.Context) {
file, _ := c.FormFile("file")
in, _ := file.Open()
defer in.Close()
out, _ := os.Create("./"+file.Filename)
defer out.Close()
io.Copy(out, in)
c.JSON(200, gin.H{
"msg":file,
})
})
r.Run(":1010") // listen and serve on 0.0.0.0:8080
}
这里和上面效果是一样得,不重复演示
附加参数
这里使用的是表单,那么之前学习的表单传参在这里依然适用。
将代码改变,增加name参数:
func main() {
r := gin.Default() //启动gin路由,携带基础中间件启动 logger and recovery (crash-free) 中间件
r.POST("testUpload", func(c *gin.Context) {
file, _ := c.FormFile("file")
name := c.PostForm("name")
in, _ := file.Open()
defer in.Close()
out, _ := os.Create("./"+file.Filename)
defer out.Close()
io.Copy(out, in)
c.JSON(200, gin.H{
"msg":file,
"name":name,
})
})
r.Run(":1010") // listen and serve on 0.0.0.0:8080
}
在postman中增加name参数,并发起请求
不仅成功拿到了文件,还将name参数获取到了
通过这种方式,就可以将文件和其他信息混合传给后台
此处传图片也是可以的,因为追根揭底传送数据时都是以流的形式进行传递的,所以本质是一样的
将文件返回前端
单个文件
将代码进行改变
func main() {
r := gin.Default() //启动gin路由,携带基础中间件启动 logger and recovery (crash-free) 中间件
r.POST("testUpload", func(c *gin.Context) {
file, _ := c.FormFile("file")
in, _ := file.Open()
defer in.Close()
out, _ := os.Create("./"+file.Filename)
defer out.Close()
io.Copy(out, in)
c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", file.Filename))
c.File("./"+file.Filename)
})
r.Run(":1010") // listen and serve on 0.0.0.0:8080
}
这里先直接给出postman请求结果
再给出图片的情况
函数c.Writer.Header().Add()在之后进行展开
批量文件
将代码修改如下:
func main() {
r := gin.Default() //启动gin路由,携带基础中间件启动 logger and recovery (crash-free) 中间件
r.POST("testUpload", func(c *gin.Context) {
form,_ := c.MultipartForm()
file := form.File["file"]
fmt.Println(file)
})
r.Run(":1010") // listen and serve on 0.0.0.0:8080
}
这里仅大概体验下,具体实现就不给出了
postman进行请求
这里可以发现是两个流的形式,因为没设置返回,所以postman中无显示东西
为了更直观观察再次改变代码,增加一部分
func main() {
r := gin.Default() //启动gin路由,携带基础中间件启动 logger and recovery (crash-free) 中间件
r.POST("testUpload", func(c *gin.Context) {
form,_ := c.MultipartForm()
file := form.File["file"]
fmt.Println(file)
for _, f := range file{
log.Println(f.Filename)
}
})
r.Run(":1010") // listen and serve on 0.0.0.0:8080
}
多文件可以通过循环实现存储,因为循环遍历时,每一次遍历都相当于处理单个文件
边栏推荐
猜你喜欢
第六届”蓝帽杯“全国大学生网络安全技能大赛 半决赛
阿里大淘系模型治理阶段性分享
Flutter introduction advanced trip (5) Image Widget
Flutter入门进阶之旅(七)GestureDetector
自定义VIEW实现应用内消息提醒上下轮播
数据挖掘-05
造自己的芯,让谷歌买单!谷歌再度开源 180nm 工艺的芯片
Flutter Getting Started and Advanced Tour (3) Text Widgets
#WeArePlay | 与更多开发者一起,探索新世界
Do you know the difference between comments, keywords, and identifiers?
随机推荐
NFS 特别注意权限的问题
系统提供的堆 VS 手动改写堆
史上最猛“员工”,疯狂吐槽亿万富翁老板小扎:那么有钱,还总穿着同样的衣服!...
kustomize入门示例及基本语法使用说明
Flutter入门进阶之旅(三)Text Widgets
[FPGA Tutorial Case 48] Image Case 8 - Realization of Converting RGB Image to HSV Image Based on FPGA, Assisted Verification by MATLAB
联通网管协议框图
透明tune proxy
NFS pays special attention to the problem of permissions
Flutter Getting Started and Advanced Tour (1) - Getting to Know Flutter
Introduction to Flutter advanced trip Dialog&Toast (10)
基于 R 语言的判别分析介绍与实践 LDA和QDA
二叉树的序列化和反序列化
ERP不规范,同事两行泪 (转载非原创)
保存Simulink仿真模型为图片或者PDF的方法
ARM板卡增加路由功能
Flutter Getting Started and Advanced Tour (3) Text Widgets
GIN Bind模式获取参数和表单验证
腾讯发布第二代四足机器人Max,梅花桩上完成跳跃、空翻
MySQL5.6到8.0的账号迁移