返回顶部
首页 > 资讯 > 后端开发 > GO >Golang GinWeb之怎么请求参数绑定和验证
  • 779
分享到

Golang GinWeb之怎么请求参数绑定和验证

2024-04-02 19:04:59 779人浏览 泡泡鱼
摘要

这篇文章主要讲解了“golang GinWEB之怎么请求参数绑定和验证”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Golang GinWeb之怎么请求参数

这篇文章主要讲解了“golang GinWEB之怎么请求参数绑定和验证”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Golang GinWeb之怎么请求参数绑定和验证”吧!

模型绑定和验证

使用模型绑定来绑定请求体到一个Go类型上. 目前支持JSON,XML,YAML以及标准表单(如foo=bar&boo=baz)的绑定.

Gin使用go-playground/validator/v10包来验证请求,  关于tags在验证中使用详见(https://godoc.org/GitHub.com/go-playground/validator#hdr-Baked_In_Validators_and_Tags)

注意:绑定前请确认结构体中需要绑定的字段标签与绑定类型一致,比如绑定jsON,设置标签: json:"fieldname"

Gin提供两种方式(类型)来完成绑定:

Must bind

1. 方法: Bind, BindJSON, BindXML, BindQuery, BindYAML, BindHeader

2. 特点: 这些方法底层使用MustBindWith方法. 如果出现绑定错误,  请求将以状态码400返回失败信息:c.AbortWithError(400, err).SetType(ErrorTypeBind),  响应中设置Content-Type头为text/plain; charset=utf-8.如果手动设置响应码,会警告响应头已经设置,比如提示:  [GIN-debug] [WARNING] Headers were already written. Wanted to override status  code 400 with 422, 如果想要更好的控制这些行为,建议使用下面对应的ShoudBind方法.

Should bind

1. 方法: ShouldBind, ShouldBindJSON, ShouldBindXML, ShouldBindQuery,  ShouldBindYAML, ShouldBindHeader

2. 特点: 这些方法底层使用ShouldBindWith. 如果出现绑定错误, 会返回错误, 开发者可以控制和恰当的处理这些错误.

当使用绑定方法时, Gin尝试根据类型头Content-Type header自动推断要使用的绑定器.  如果你已经确认需要绑定的类型,可以直接使用底层的MustBindWith或ShouldBindWith方法.

你也可以针对特殊的字段指定required标签值, 如果某个字段指定了:binding:"required"标签,  但是在绑定时该字段为空会返回错误.

如以下代码绑定JSON:

package main  import (   "github.com/gin-gonic/gin"   "net/Http" )  // Binding from JSON type Login struct {   User string `fORM:"user" json:"user" xml:"user"  binding:"required"` //分别定义form,json,xml,binding等标签   //PassWord string `form:"password" json:"password" xml:"password" binding:"required"`   Password string `form:"password" json:"password" xml:"password" binding:"-"` }  func main() {   router := gin.Default()    // Example for binding JSON ({"user": "manu", "password": "123"})   router.POST("/loginJSON", func(c *gin.Context) {     var json Login     if err := c.ShouldBindJSON(&json); err != nil {       c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})       return     }      if json.User != "manu" || json.Password != "123" {       c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})       return     }      c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})   })    // Example for binding XML (   //  <?xml version="1.0" encoding="UTF-8"?>   //  <root>   //    <user>user</user>   //    <password>123</password>   //  </root>)   router.POST("/loginXML", func(c *gin.Context) {     var xml Login     if err := c.ShouldBindXML(&xml); err != nil {       c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})       return     }      if xml.User != "manu" || xml.Password != "123" {       c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})       return     }      c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})   })    // Example for binding a html form (user=manu&password=123)   router.POST("/loginForm", func(c *gin.Context) {     var form Login     // This will infer what binder to use depending on the content-type header.     if err := c.ShouldBind(&form); err != nil {       c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})       return     }      if form.User != "manu" || form.Password != "123" {       c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})       return     }      c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})   })    // Listen and serve on 0.0.0.0:8080   router.Run(":8080") }  //模拟请求: curl -v -X POST http://localhost:8080/loginJSON -H 'content-type: application/json' -d '{ "user": "manu", "password": "123" }'

跳过验证: 与binding:"required"标签对应的是binding:"-", 表示该字段不做绑定, 所以绑定时该字段为空不会报错.

自定义验证器

你也可以自己注册一个自定义验证器,  示例代码请参考(https://github.com/gin-gonic/examples/blob/master/custom-validation/server.go)

package main  import (   "net/http"   "time"    "github.com/gin-gonic/gin"   "github.com/gin-gonic/gin/binding"   "github.com/go-playground/validator/v10" )  // Booking contains binded and validated data. // Booking结构中定义了包含绑定器和日期验证器标签 type Booking struct {   CheckIn  time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`  //登记时间   CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn" time_format:"2006-01-02"`  //gtfield=CheckIn表示结账时间必须大于登记时间 }  // 定义日期验证器 var bookableDate validator.Func = func(fl validator.FieldLevel) bool {   date, ok := fl.Field().Interface().(time.Time)  //利用反射获取到字段值 -> 转为接口 -> 类型断言(时间类型)   if ok {     today := time.Now()     if today.After(date) {  //如果当前时间在checkIn字段时间之后,返回false,即登记时间不能早于当前的时间       return false     }   }   return true }  func main() {   route := gin.Default()   //对binding.Validator.Engine()接口进行类型断言,断言类型为Validate结构,如果断言成功,就将自定义的验证器注册到Gin内部   if v, ok := binding.Validator.Engine().(*validator.Validate); ok {     // - if the key already exists, the previous validation function will be replaced. 该注册方法会将已经存在的验证器替换     // - this method is not thread-safe it is intended that these all be reGIStered prior to any validation     // 注册方法不是线程安全的, 在验证开始前,需要保证所有的验证器都注册成功     v.RegisterValidation("bookabledate", bookableDate)   }    route.GET("/bookable", getBookable)   route.Run(":8085") }  func getBookable(c *gin.Context) {   var b Booking   if err := c.ShouldBindWith(&b, binding.Query); err == nil {     c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})   } else {     c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})   } }  //模拟请求: // 登记时间和结账时间符合条件 //$ curl "localhost:8085/bookable?check_in=2030-04-16&check_out=2030-04-17" //{"message":"Booking dates are valid!"} // // 登记时间在结账时间之后, 不满足gtfield校验规则 //$ curl "localhost:8085/bookable?check_in=2030-03-10&check_out=2030-03-09" //{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"} // // 登记时间在当前时间之前,不满足自定义的验证器 //$ curl "localhost:8085/bookable?check_in=2000-03-09&check_out=2000-03-10" //{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}%

另外结构体级别的验证采用如下的方式注册, v.RegisterStructValidation(UserStructLevelValidation,  User{}), 请参考struct-lvl-validation  example(https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations)

感谢各位的阅读,以上就是“Golang GinWeb之怎么请求参数绑定和验证”的内容了,经过本文的学习后,相信大家对Golang GinWeb之怎么请求参数绑定和验证这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

您可能感兴趣的文档:

--结束END--

本文标题: Golang GinWeb之怎么请求参数绑定和验证

本文链接: https://lsjlt.com/news/84275.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Golang GinWeb之怎么请求参数绑定和验证
    这篇文章主要讲解了“Golang GinWeb之怎么请求参数绑定和验证”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Golang GinWeb之怎么请求参数...
    99+
    2024-04-02
  • Golang GinWeb框架之如何理解绑定请求字符串/URI/请求头/复选框/表单类型
    这篇文章主要讲解了“Golang GinWeb框架之如何理解绑定请求字符串/URI/请求头/复选框/表单类型”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“G...
    99+
    2024-04-02
  • Spring Boot怎么实现请求参数校验
    这篇文章主要介绍了Spring Boot怎么实现请求参数校验的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Spring Boot怎么实现请求参数校验文章都会有所收获,下面我们一...
    99+
    2024-04-02
  • SpringBoot中怎么实现请求参数校验
    在Spring Boot中,可以使用JSR 303规范中的注解来实现请求参数的校验。具体步骤如下: 在Controller类中的请...
    99+
    2024-03-08
    SpringBoot
  • POST请求和GET请求怎么传递和接收解析参数
    本篇内容介绍了“POST请求和GET请求怎么传递和接收解析参数”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成...
    99+
    2024-04-02
  • EBS怎么查找运行请求时间和参数等
    这篇文章主要介绍“EBS怎么查找运行请求时间和参数等”,在日常操作中,相信很多人在EBS怎么查找运行请求时间和参数等问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”EBS怎么查...
    99+
    2024-04-02
  • Chainer怎么进行超参数调优和模型验证
    Chainer是一个深度学习框架,通常使用Grid Search、Random Search、Bayesian Optimizati...
    99+
    2024-04-02
  • CNTK怎么实现超参数调优和模型验证
    要在CNTK中实现超参数调优和模型验证,可以采用以下步骤: 定义超参数空间:首先定义要调优的超参数空间,包括学习率、批大小、隐藏...
    99+
    2024-04-02
  • vue中this.$http.post()跨域和请求参数丢失怎么解决
    今天小编给大家分享一下vue中this.$http.post()跨域和请求参数丢失怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来...
    99+
    2023-06-29
  • AngularJS双向数据绑定原理之$watch、$apply和$digest怎么用
    小编给大家分享一下AngularJS双向数据绑定原理之$watch、$apply和$digest怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!背景AngularJS开发者都想知道双向...
    99+
    2024-04-02
  • springBoot之怎么获取接口请求数据和返回数据实现日志
    这篇文章主要介绍“springBoot之怎么获取接口请求数据和返回数据实现日志”,在日常操作中,相信很多人在springBoot之怎么获取接口请求数据和返回数据实现日志问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作