26-gin框架参数处理以及文件上传

获取参数
获取querystring参数

querystring指的是是URL中?后面携带的参数,例如:user/search?username=小男孩&address=天通苑。获取请求的querystring参数的方法如下:

// 获取querystring参数
func QueryDemo() {
	// 声明一个默认的路由引擎
	r := gin.Default()
	r.GET("/user/search", func(ctx *gin.Context) {
		username := ctx.DefaultQuery("username", "小男孩") // 如果username获取不到,就用默认值
		address := ctx.Query("address")
		// 输出json给调用房
		ctx.JSON(http.StatusOK, gin.H{
			"message":  "ok",
			"username": username,
			"address":  address,
		})
	})

	r.Run(":8080")
}

结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RYAPMB7u-1657250004386)(/Users/alblue/Library/Application Support/typora-user-images/image-20220330105805818.png)]

获取form参数

当前端请求的数据通过form表单提交时,例如向/user/search发送一个POST请求,获取请求数据的方式如下:

// 获取form参数
func FormDemo() {
	// 注册一个默认的路由
	r := gin.Default()
	r.POST("/user/search", func(ctx *gin.Context) {
		// DefaultPOstForm取不到值会返回指定的默认值
		// username := ctx.DefaultPOstForm("username","小王子")
		username := ctx.PostForm("username")
		address := ctx.PostForm("address")

		// 输出json结果
		ctx.JSON(http.StatusOK, gin.H{
			"message":  "ok",
			"username": username,
			"address":  address,
		})
	})

	// 启动
	r.Run(":8080")
}

结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EIp8FNNR-1657250004387)(/Users/alblue/Library/Application Support/typora-user-images/image-20220330110751783.png)]

获取Json参数

当前端请求的数据通过JSON提交时,例如向/json发送一个POST请求,则获取请求参数的方式如下:

r.POST("/json", func(c *gin.Context) {
	// 注意:下面为了举例子方便,暂时忽略了错误处理
	b, _ := c.GetRawData()  // 从c.Request.Body读取请求数据
	// 定义map或结构体
	var m map[string]interface{}
	// 反序列化
	_ = json.Unmarshal(b, &m)

	c.JSON(http.StatusOK, m)
})

更便利的获取请求参数的方式,参考下面参数绑定小节。

获取path参数

请求的参数通过URL路径传递,例如:/user/serach/小王子/沙河。获取请求URL路径参数的方式如下。

// 获取path参数
func PathDemo() {
	// 注册一个默认的路由
	r := gin.Default()
	r.GET("/user/serach/:user/:address", func(ctx *gin.Context) {
		username := ctx.Param("user")
		address := ctx.Param("address")

		//输出json结果给调用房
		ctx.JSON(http.StatusOK, gin.H{
			"message":  "ok",
			"username": username,
			"address":  address,
		})
	})

	r.Run(":8080")
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dIpUc48g-1657250004387)(/Users/alblue/Library/Application Support/typora-user-images/image-20220330112440560.png)]

参数绑定

为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的Content-Type识别请求数据类型并利用反射机制自动提取请求中的QueryStringform表单JSONXML等参数到结构体中。下面的示例代码演示了.ShouldBind()强大的功能,它能够基于请求自动提取JSONform表单QueryString类型的数据,并把值绑定到指定的结构体对象。

注意:

  1. 字段首字母大写,并且tag要对应上
  2. 要传指针类型

绑定JSON示例

// 参数绑定
type Login struct {
	User     string `form:"user" json:"user" binding:"required"`
	Password string `form:"password" json:"password" binding:"required"`
}

func ShouldBindDemo1() {
	// 注册默认路由
	r := gin.Default()

	//绑定JSON示例({"user": "王磊", "password": "123456"})
	r.POST("/loginJSON", func(ctx *gin.Context) {
		var login Login

		if err := ctx.ShouldBind(&login); err == nil {
			fmt.Printf("login info:%#v\n", login)
			ctx.JSON(http.StatusOK, gin.H{
				"user":     login.User,
				"password": login.Password,
			})
		} else {
			ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
	})

	//启动
	r.Run(":8080")

}

结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w4hbR05s-1657250004388)(/Users/alblue/Library/Application Support/typora-user-images/image-20220330142055583.png)]

绑定form示例

// 参数绑定
type Login struct {
	User     string `form:"user" json:"user" binding:"required"`
	Password string `form:"password" json:"password" binding:"required"`
}


// 绑定表单form示例(user=王磊&password=123456)
func ShouldBindDemo2() {
	// 注册路由
	r := gin.Default()

	//绑定form示例(user=王磊&password=123456)
	r.POST("/loginFORM", func(ctx *gin.Context) {
		var login Login

		if err := ctx.ShouldBind(&login); err == nil {
			fmt.Printf("login info :%#v\n", login)
			ctx.JSON(http.StatusOK, gin.H{
				"result":   "ok",
				"user":     login.User,
				"password": login.Password,
			})
		} else {
			ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
	})

	// 启动
	r.Run(":8080")
}

结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vjB9PC98-1657250004388)(/Users/alblue/Library/Application Support/typora-user-images/image-20220330143411292.png)]

绑定QueryString示例

// 参数绑定
type Login struct {
	User     string `form:"user" json:"user" binding:"required"`
	Password string `form:"password" json:"password" binding:"required"`
}

func ShouldBindDemo3() {
	// 注册默认路由
	r := gin.Default()

	//绑定QueryString示例 (/loginQuery?user=q1mi&password=123456)
	r.GET("/loginQuery", func(ctx *gin.Context) {
		var login Login

		if err := ctx.ShouldBind(&login); err == nil {
			fmt.Printf("login info:%#v\n", login)
			ctx.JSON(http.StatusOK, gin.H{
				"result":   "ok",
				"user":     login.User,
				"password": login.Password,
			})
		} else {
			ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
	})

	//启动
	r.Run(":8080")
}

结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XgYt3lVG-1657250004388)(/Users/alblue/Library/Application Support/typora-user-images/image-20220330144429731.png)]

注意

ShouldBind会按照下面的顺序解析请求中的数据完成绑定:

1、如果是GET请求,只使用Form绑定引擎(query)。

2、如果是POST请求,首先检查content-type是否为JSON或者XML,然后再使用Formform-data)。

文件上传
单个文件上传

文件上传前端页面代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>上传文件示例</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="f1">
    <input type="submit" value="上传">
</form>
</body>
</html>

后端gin框架部分代码:

// 单个文件上传

func UploadSingleFile() {

	r := gin.Default()

	// 1、访问浏览器时,可以获取一个上传文件页面
	r.LoadHTMLFiles("/Users/alblue/Documents/路飞go/day11/作业/gin/templates/uploadfile/upload.html")
	r.GET("upload", func(ctx *gin.Context) {
		ctx.HTML(http.StatusOK, "upload.html", nil)
	})

	// 2、post上传文件
	// 处理multipart forms提交文件时默认的内存限制是32MiB
	// 可以通过下面的方式修改
	// router.MaxMultipartMemory = 8 << 20  // 8 MiB
	r.POST("/upload", func(ctx *gin.Context) {
		// 单个文件
		file, err := ctx.FormFile("f1")
		if err != nil {
			ctx.JSON(http.StatusBadRequest, gin.H{
				"error": err.Error(),
			})
			return
		}

		log.Println(file.Filename)                                                        // 拿到上传文件的名字
		dst := fmt.Sprintf("/Users/alblue/Documents/路飞go/day11/作业/gin/%s", file.Filename) // 定义上传文件的位置
		// 上传文件到指定目录
		ctx.SaveUploadedFile(file, dst)
		ctx.JSON(http.StatusOK, gin.H{
			"message": fmt.Sprintf("%s uploaded syccess", file.Filename),
		})
	})

	// 启动
	r.Run(":8080")
}

结果:

1、浏览器访问http://127.0.0.1:8080/upload, 进入上传文件的html页面.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mBE4jawk-1657250004389)(/Users/alblue/Library/Application Support/typora-user-images/image-20220330151736688.png)]

2、选择文件上传

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bq0kqJ9M-1657250004389)(/Users/alblue/Library/Application Support/typora-user-images/image-20220330151822521.png)]

多文件上传

前端代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>上传文件示例</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    <div>
        <input type="file" name="f1">
    </div>
    <div>
        <input type="file" name="f1">
    </div>
    <input type="submit" value="上传">
</form>
</body>
</html>

后端go代码

// 多个文件上传

func UploadMultiFile() {

	// 注册默认路由
	r := gin.Default()

	// 1、 获取上传文件html页面
	r.LoadHTMLFiles("/Users/alblue/Documents/路飞go/day11/作业/gin/templates/uploadfile/upload.html")
	r.GET("/upload", func(ctx *gin.Context) {
		ctx.HTML(http.StatusOK, "upload.html", nil)
	})

	// 2、 上传文件
	// 处理multipart forms提交文件时默认的内存限制是32 MiB
	// 可以通过下面的方式修改
	// router.MaxMultipartMemory = 8 << 20  // 8 MiB
	r.POST("/upload", func(ctx *gin.Context) {
		form, err := ctx.MultipartForm()
		if err != nil {
			panic(err)
		}
		files := form.File["f1"] // form.File["f1"] 获取的事前端中name=f1

		log.Println(files)
		// 遍历
		for _, file := range files {
			log.Println(file.Filename)
			dst := fmt.Sprintf("/Users/alblue/Documents/路飞go/day11/作业/gin/%s", file.Filename)
			// 上传文件到指定目录
			ctx.SaveUploadedFile(file, dst)
		}
		ctx.JSON(http.StatusOK, gin.H{
			"message": fmt.Sprintf("%v file upload sucess", len(files)),
		})

	})

	// 运行
	r.Run(":8888")
}

结果:

1、浏览器访问http://127.0.0.1:8888/upload, 进入上传文件的html页面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RgnHsdM9-1657250004390)(/Users/alblue/Library/Application Support/typora-user-images/image-20220330155648985.png)]

2、上传多个文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vC3pr2Nb-1657250004390)(/Users/alblue/Library/Application Support/typora-user-images/image-20220330155708430.png)]

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值