当前位置:网站首页>GIN Bind模式获取参数和表单验证

GIN Bind模式获取参数和表单验证

2022-08-09 12:44:00 一叶知秋@qqy

前言
感谢开源项目gin-vue-admin,以及1010工作室的教程,项目文档
我只是在跟着学习,然后记录下笔记而已,可能会有新的代码加入,但是本质还是跟着学习的一个过程。
所谓的绑定就是先建立一个结构体,然后将接收到的参数通过绑定的形式直接映射上去

bind模式以及如何使用

在使用绑定模式时有两种方式,即must bind和should bind。

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

  • Mwthods:
    ShouldBind, ShouldBindJSON, ShouldBindXML, ShouldBindQuery, ShouldBindYAML
  • Behavior:
    这些方法底层使用ShouldBindWith如果存在绑定错误,则返回错误,开发人员可以正确请求和错误。

当我们使用绑定方法时,Gin会根据Content-Type推断出使用哪种绑定器,如果你确定你绑定的是什么,你可以使用MustBindWith或者BindingWith

ShouldBindJSON

在goland中写下如下代码:

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() //启动gin路由,携带基础中间件启动 logger and recovery (crash-free) 中间件

	r.POST("testBind", func(c *gin.Context) {
    
		var p PostParams
		err := c.ShouldBindJSON(&p)
		if err != nil{
    
			c.JSON(200, gin.H{
    
				"msg":"报错了",
				"data":gin.H{
    },
			})
		}else{
    
			c.JSON(200, gin.H{
    
				"msg":"成功了",
				"data":p,
			})
		}
	})
	r.Run(":1010") // listen and serve on 0.0.0.0:8080
}

在这里做了以下几件事:

创建PostParams结构体

在里面做出如下定义:

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

可以看出这里面的三个元素都允许被绑定到各自对应的json上了。

使用ShouldBindJSON

首先实例化PostParams

var p PostParams

调用接口实现映射解析,并返回错误码

err := c.ShouldBindJSON(&p)

根据返回结果做出响应

if err != nil{
    
	c.JSON(200, gin.H{
    
		"msg":"报错了",
		"data":gin.H{
    },
	})
}else{
    
	c.JSON(200, gin.H{
    
		"msg":"成功了",
		"data":p,
	})
}

postman组织请求

在这里插入图片描述

在这里插入图片描述
可以看出已经得到了正确的返回响应

ShouldBindUri

修改PostParams结构体

在里面做出添加如下uri的字段:

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

可以看出这里面的三个元素由都允许被绑定到各自对应的uri上了。

更改访问网址

因为最开始时展示的是json的绑定,即从body内去取参数,但是现在使用uri大的方式,要将参数放到网址内。
所以将原来的网址部分的testBind替换为

testBind/:name/:sge/:sex

并将ShouldBindJSON更换为ShouldBindUri

组织postman访问

在这里插入图片描述
在这里插入图片描述

ShouldBindQuery

修改PostParams结构体

在里面做出添加如下Query对应form的字段:

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"`
}

更改访问网址

将原来的网址部分恢复为testBind替换
并将ShouldBindUri更换为ShouldBindQuery

组织postman访问

在这里插入图片描述
在这里插入图片描述

ShouldBind

上面的绑定可以看到同时只能接收一种类型,所以当同时可能存在多种类型时,显然已经不是这样子可以处理的了,所以在这种情况时可以使用ShouldBind

如果是Post, 首先判断 content-type 的类型 JSON or XML, 然后使用对应的绑定器获取数据.

See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48

如下面postman截图中所示
在这里插入图片描述

表单验证binding

修改PostParams结构体

在里面添加如下binding的字段:

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

在这里加入required修饰符,这时如果加了修饰符的参数过来是空的,那么会直接报错
将绑定器换为ShouldBindJSON

组织postman

在这里插入图片描述
可以发现,当存在空的请求时直接报错了。
在代码中加入打印,查看下具体的错误信息
在这里插入图片描述
显然是因为必填项每天没有填写造成的错误

自定义验证器

首先在PostParams结构体的binding加上一个自定义的标签mustBig,然后定义一个验证器,一这个标签名为例:

func mustBig(fl validator.FieldLevel)bool{
    
	if(fl.Field().Interface().(int) <= 18){
    
		return false
	}
	return true
}

在函数内部传入validator.FieldLevel对象,内部采用反射的形式断言出来,并作判断,返回truw 或者 false返回当前验证规则是否通过

在main函数内将这个验证器挂载

if v, ok := binding.Validator.Engine().(*validator.Validate); ok{
    
		v.RegisterValidation("mustBig", mustBig)
	}

给出整个代码:

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"`
	Age int `json:"age" binding:"required,mustBig"`
	Sex bool `json:"sex"`
}

func mustBig(fl validator.FieldLevel)bool{
    
	if(fl.Field().Interface().(int) <= 18){
    
		return false
	}
	return true
}



func main() {
    
	r := gin.Default() //启动gin路由,携带基础中间件启动 logger and recovery (crash-free) 中间件
	r.POST("testBind", func(c *gin.Context) {
    
		if v, ok := binding.Validator.Engine().(*validator.Validate); ok{
    
			v.RegisterValidation("mustBig", mustBig)
		}
		var p PostParams
		err := c.ShouldBindJSON(&p)
		if err != nil{
    
			fmt.Println(err)
			c.JSON(200, gin.H{
    
				"msg":"报错了",
				"data":gin.H{
    },
			})
		}else{
    
			c.JSON(200, gin.H{
    
				"msg":"成功了",
				"data":p,
			})
		}
	})
	r.Run(":1010") // listen and serve on 0.0.0.0:8080
}

postman组织请求1

在这里插入图片描述
这时请求的age是28大于验证器中的18,所以成功

postman组织请求2

在这里插入图片描述
这时请求的age是8小于验证器中的18,所以失败
所以使用binding不仅可以表单验证,还可以自定义验证器,这给代码带来了很大的发挥空间

原网站

版权声明
本文为[一叶知秋@qqy]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_41004932/article/details/119514374