【gin学习笔记】03使用bind绑定参数和参数验证

本次学习参考视频https://www.bilibili.com/video/BV1gt4y1173C?spm_id_from=333.1007.top_right_bar_window_history.content.click

bind是工作中比较常用的方法。bind就是先创立一个结构体,然后把扔过来的参数通过一种绑定的形式直接映射到某一个结构体的实例上去。
若要将请求主体绑定到结构体中,请使用模型绑定,目前支持JSON、XML、YAML和标准表单值(foo=bar&boo=baz)的绑定。
需要在绑定的字段上设置tag,比如,绑定格式为json,需要这样设置 json:“fieldname”
此外,Gin还提供了两套绑定方法:

  • Must bind
    • Methods - Bind, BindJSON, BindXML, BindQuery, BindYAML
    • Behavior - 这些方法底层使用 MustBindWith,如果存在绑定错误,请求将被以下指令中止c.AbortWithError(400, err).SetType(ErrorTypeBind),响应状态代码会被设置为400,请求头Content-Type被设置为text/plain; charset=utf-8。注意,如果你试图在此之后设置响应代码,将会发出一个警告 [GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422,如果你希望更好地控制行为,请使用ShouldBind相关的方法
  • Should bind
    • Methods - ShouldBind, ShouldBindJSON, ShouldBindXML, ShouldBindQuery, ShouldBindYAML
    • Behavior - 这些方法底层使用 ShouldBindWith,如果存在绑定错误,则返回错误,开发人员可以正确处理请求和错误。

平常开发工作中尽量用ShouldBind的方法,如果想要使用bind那么就必须要设置tag。

下面跑几个例子来体验下。

ShouldBindJSON
传入一个json的body

package main

import "github.com/gin-gonic/gin"

type PostParams struct {
	Name string `json:"name"` 
	Age  int    `json:"age"`
	Sex  bool   `json:"sex"`
}

func main() {
	r := gin.Default()
	r.POST("/testBind", func(c *gin.Context) {
		var p PostParams
		err := c.ShouldBindJSON(&p) //将传过来的json赋给p
		if err != nil {
			c.JSON(200, gin.H{
				"msg":  "bindjson报错了",
				"data": gin.H{},
			})
		} else {
			c.JSON(200, gin.H{
				"msg":  "请求成功",
				"data": p, //如果请求成功则把p的值打印出来
			})
		}
	})
	r.Run(":8080")
}

在postman发送一个请求,得到的结果如下。
在这里插入图片描述
ShouldBindUri
shouldbinduri的请求参数应该写在uri里

package main

import "github.com/gin-gonic/gin"

type PostParams struct{
	Name string `json:"name"  uri:"name"`
	Age int `json:"age" uri:"age"`
	Sex bool `json:"sex" uri:"sex"`
}

func main(){
	r := gin.Default()
	r.POST("/testBind/:name/:age/:sex", func(c *gin.Context){
		var p PostParams
		err := c.ShouldBindUri(&p)
		if err !=nil{
			c.JSON(200, gin.H{
				"msg": "报错了",
				"data": gin.H{},
			})
		}else{
			c.JSON(200, gin.H{
				"msg": "binduri请求成功",
				"data": p,
			})
		}
	})
	r.Run(":8080")
}

这里记得要在PostParams struct的定义里写上uri: “xxx”
uri中按顺序写入name,age和sex的参数
在这里插入图片描述
ShouldBindQuery
shouldbindquery的请求参数也是写在uri里,跟shouldbinduri稍微有些区别

package main

import "github.com/gin-gonic/gin"

type PostParams struct{
	Name string `json:"name"  uri:"name" form:"name"`
	Age int `json:"age" uri:"age" form:"age"`
	Sex bool `json:"sex" uri:"sex" form:"sex"`
}
//http://localhost:8080/testBind?age=18&name=kaka&sex=true
func main(){
	r := gin.Default()
	r.POST("/testBind", func(c *gin.Context){
		var p PostParams
		err := c.ShouldBindQuery(&p)
		if err !=nil{
			c.JSON(200, gin.H{
				"msg": "报错了",
				"data": gin.H{},
			})
		}else{
			c.JSON(200, gin.H{
				"msg": "bindquery请求成功",
				"postdata": p,
			})
		}
	})
	r.Run(":8080")
}

在这里插入图片描述
ShouldBind

func startPage(c *gin.Context) {
	var person Person
	// If `GET`, only `Form` binding engine (`query`) used.
	// 如果是Get,那么接收不到请求中的Post的数据??
	// 如果是Post, 首先判断 `content-type` 的类型 `JSON` or `XML`, 然后使用对应的绑定器获取数据.
	// See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
	if c.ShouldBind(&person) == nil {
		log.Println(person.Name)
		log.Println(person.Address)
		log.Println(person.Birthday)
	}

	c.String(200, "Success")
}

shouldbind首先判断content-type信息来使用对应的绑定器获取数据。
在这里插入图片描述
从前面的例子可以看出,当我们使用shouldbind方法时,Gin会根据Content-Type推断出使用哪种绑定器,如果你确定你绑定的是什么,你可以使用MustBindWith或者BindingWith,然后在根据对应的方法来传参。

绑定器
你还可以给字段指定特定规则的修饰符,如果一个字段用binding:"required"修饰,并且在绑定时该字段的值为空,那么将返回一个错误。
在shouldbindjson中加修饰符

type PostParams struct {
	Name string `json:"name" binding:"required"` //加上binding:"required"后如果传过来的内容为空,则直接报错。
	Age  int    `json:"age" binding:"required"`
	Sex  bool   `json:"sex" binding:"required"`
}```

```go
在这里插入代码片

加上一个错误打印的代码
在这里插入图片描述

然后传参的时候只传age字段,如下图
在这里插入图片描述
错误日志里显示如下:
在这里插入图片描述
说明加上binding:"required"修饰后,字段里的值是必填的。

假如我们想要传入的age参数必须要大于18岁,否则就报错,那么怎么实现?
代码实现如下

package main

import (
	"fmt"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/validator/v10"
)

type PostParams struct {
	Name string `json:"name" ` //加上binding:"required"后如果传过来的内容为空,则直接报错。
	Age  int    `json:"age" binding:"required,mustBig"`
	Sex  bool   `json:"sex" `
}
//增加了mustBig func
func mustBig(fl validator.FieldLevel) bool {
	fmt.Println(fl.Field().Interface().(int))
	if fl.Field().Interface().(int) <= 18 { //通过反射的形式进行判断
		return false
	}
	return true
}

func main() {
	r := gin.Default()
	//然后这里增加了一个判断
	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
		v.RegisterValidation("mustBig", mustBig)
	}

	r.POST("/testBind", func(c *gin.Context) {
		var p PostParams
		err := c.ShouldBindJSON(&p) //将传过来的json赋给p
		if err != nil {
			fmt.Println(err.Error())
			c.JSON(200, gin.H{
				"msg":  "bindjson报错了",
				"data": gin.H{},
			})
		} else {
			c.JSON(200, gin.H{
				"msg":  "请求成功",
				"data": p, //如果请求成功则把p的值打印出来
			})
		}
	})
	r.Run(":8080")
}

在这里插入图片描述
传一个age=8的参数进去后得到报错如下。
在这里插入图片描述

总结

bind就是先创立一个结构体,然后把扔过来的参数通过一种绑定的形式直接映射到某一个结构体的实例上去

  • bind模式如何使用(一般用shouldbind)

    • bind模式一定要设置tag
    • bind可以绑json、form、uri
  • shouldbind

    • 表单验证
      • 即binding:“required”
    • 自定义验证
      • 即上面的那个限制18岁的传参
  • shouldbind

    • ShouldBindJSON使用方法
      • post一个json的body
    • ShouldBindJQuery使用方法
      • post http://127.0.0.1:8080/testBind?name=kaka&age=19&sex=false
    • ShouldBindUri使用方法
      • post http://127.0.0.1:8080/testBind/jack/18/true
    • ShouldBind使用方法
      • shouldbind会根据header里面的Content-Type来自动选择绑定器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值