当前位置:网站首页>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不仅可以表单验证,还可以自定义验证器,这给代码带来了很大的发挥空间
边栏推荐
- 【FPGA教程案例48】图像案例8——基于FPGA的RGB图像转化为HSV图像的实现,通过MATLAB进行辅助验证
- ViewPager fragments of nested data blank page abnormal problem analysis
- [HCIP Continuous Update] Principle and Configuration of IS-IS Protocol
- 系统提供的堆 VS 手动改写堆
- 十六进制字符→十进制数字
- 生成上传密钥和密钥库
- Report: The number of students who want to learn AI has increased by 200%, and there are not enough teachers
- 链表噩梦之一?5000多字带你弄清它的来龙去脉
- Flutter introduction advanced trip (5) Image Widget
- 自定义VIEW实现应用内消息提醒上下轮播
猜你喜欢
随机推荐
26、管道参数替换命令xargs
Manchester city launch emotional intelligence scarf can be detected, give the fans
Say goodbye to the AI era of hand looms
FPGA-近日工作总结
史上最猛“员工”,疯狂吐槽亿万富翁老板小扎:那么有钱,还总穿着同样的衣服!...
5G China unicom general exception handling
kustomize入门示例及基本语法使用说明
ABAP interview questions: how to use the System CALL interface of the ABAP programming language, direct execution ABAP server operating System's shell command?
Flutter入门进阶之旅(四)文本输入Widget TextField
telnet+ftp 对设备进行 操控 和 升级
正则引擎的几种分类
安踏携手华为运动健康共同验证冠军跑鞋 创新引领中国体育
JVM内存泄漏和内存溢出的原因
Flutter入门进阶之旅(一)-初识Flutter
ansible-cmdb friendly display ansible collects host information
第六届”蓝帽杯“全国大学生网络安全技能大赛 半决赛
Flutter入门进阶之旅(三)Text Widgets
数据挖掘-05
R 语言 2010.1至2021.12艾滋病每月发病人数 时间序列分析
Compensation transaction and idempotency guarantee based on CAP components