Gin除了模型绑定还提供了模型验证功能。你可以给字段指定特定的规则标签,如果一个字段用binding:"required"标签修饰,在绑定时该字段的值为空,那么将返回一个错误。开发web api的时候大部分参数都是需要验证的,比如email参数要验证是否是邮箱格式、phone参数要验证是否是手机号格式等等,使用模型验证方法可以将验证过程隔离在业务之外。

内置的验证标签

Gin通过集成go-playground/validator提供模型验证功能,并提供了很多常用验证规则可以满足我们大部分的开发需求。我们通过一个例子看一下怎么使用这些验证标签。

type AddUserRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"` // 登录密码
Nickname string `json:"nickname" binding:"required"` // 昵称
Mobile string `json:"mobile"` // 手机号
Email string `json:"email" binding:"required,email"` // 邮箱地址
} func AddUser(c *gin.Context) {
req := sysUser.AddUserRequest{}
if err := c.ShouldBind(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
...
c.String(http.StatusOK, "")
}

在Username字段上增加了binding:"required"标签,代表gin会验证参数为必填项,如果没有为Username字段提供值ShouldBind返回的err中会包含相应的错误内容。Email字段增加了binding:"required,email"标签,这是一个组合验证,代表Email是必填项的同时还要是一个正确的邮箱格式的字符串。

下面例子可以看到在未通过模型验证时,接口返回的错误信息。

请求:

{
"username":"",
"password":"123qwe",
"nickname": "昵称",
"mobile": "13322323232",
"email": "",
"qq": "234123412312"
}

响应:

{
"error": "Key: 'AddUserRequest.Username' Error:Field validation for 'Username' failed on the 'required' tag\nKey: 'AddUserRequest.Email' Error:Field validation for 'Email' failed on the 'required' tag"
}

自定义验证

有时候内置的验证规则可能不能满足业务需求,这样就需要自定义验证规则。大致两个步骤,1.定义一个验证方法。2.把这个方法注册为验证规则。

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"`
} 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) {
return false
}
}
return true
} func main() {
route := gin.Default() if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
v.RegisterValidation("bookabledate", bookableDate)
}
...
}

这里添加了一个叫做bookabledate的验证规则,验证一下参数是否大于今天。使用RegisterValidation("bookabledate", bookableDate)方法注册为验证规则,并且在CheckIn字段上增加了binding:"required,bookabledate"标签。如果验证失败会返回错误信息:

Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"

自定义错误消息

目前错误消息还是英文的,对于国内用户很不友好,接口报错的时候基本不可能把这种错误消息返回给用户看。go-playground/validator提供了错误信息的翻译,至少先解决英文错误的问题。在项目下新增validator/init.go文件。

package validator

import (
"github.com/gin-gonic/gin/binding"
"github.com/go-playground/locales/zh"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
zh_translations "github.com/go-playground/validator/v10/translations/zh"
) var (
uni *ut.UniversalTranslator
validate *validator.Validate
trans ut.Translator
) func init() {
translator := zh.New()
uni = ut.New(translator, translator)
trans, _ = uni.GetTranslator("zh")
validate := binding.Validator.Engine().(*validator.Validate)
_ = zh_translations.RegisterDefaultTranslations(validate, trans)
} func Translate(err error) string {
var result string errors := err.(validator.ValidationErrors) for _, err := range errors {
result += err.Translate(trans) + ";"
}
return result
}

在handler中调用validator.Translate方法获取错误消息的中文翻译。

func AddUser(c *gin.Context) {
req := sysUser.AddUserRequest{}
if err := c.ShouldBind(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": validator.Translate(err)})
return
}
...
c.String(http.StatusOK, "")
}

这样访问接口时会看到中文的错误信息:

{
"error": "Username为必填字段;"
}

文章出处:基于gin的golang web开发:模型验证

基于gin的golang web开发:模型验证的更多相关文章

  1. 基于gin的golang web开发:模型绑定

    在前两篇文章介绍路由的时候,我们了解到gin可用通过类似DefaultQuery或DefaultPostForm等方法获取到前端提交过来的参数.参数不多的情况下也很好用,但是想想看,如果接口有很多个参 ...

  2. 基于gin的golang web开发:永远不要相信用户的输入

    作为后端开发者我们要记住一句话:"永远不要相信用户的输入",这里所说的用户可能是人,也可能是另一个应用程序."永远不要相信用户的输入"是安全编码的准则,也就是说 ...

  3. 基于gin的golang web开发:实现用户登录

    前文分别介绍过了Resty和gin-jwt两个包,Resty是一个HTTP和REST客户端,gin-jwt是一个实现了JWT的Gin中间件.本文将使用这两个包来实现一个简单的用户登录功能. 环境准备 ...

  4. 基于gin的golang web开发:mysql增删改查

    Go语言访问mysql数据库需要用到标准库database/sql和mysql的驱动.标准库的Api使用比较繁琐这里再引入另一个库github.com/jmoiron/sqlx. go get git ...

  5. 基于gin的golang web开发:中间件

    gin中间件(middleware)提供了类似于面向切面编程或路由拦截器的功能,可以在请求前和请求之后添加一些自定义逻辑.实际开发中有很多场景会用到中间件,例如:权限验证,缓存,错误处理,日志,事务等 ...

  6. 基于gin的golang web开发:认证利器jwt

    JSON Web Token(JWT)是一种很流行的跨域认证解决方案,JWT基于JSON可以在进行验证的同时附带身份信息,对于前后端分离项目很有帮助. eyJhbGciOiJIUzI1NiIsInR5 ...

  7. 基于gin的golang web开发:路由

    Gin是一个用Golang编写的HTTP网络框架.它的特点是类似于Martini的API,性能更好.在golang web开发领域是一个非常热门的web框架. 启动一个Gin web服务器 使用下面的 ...

  8. 基于gin的golang web开发:路由二

    在基于gin的golang web开发:路由中我们介绍了Gin的路由和一些获取链接中参数的方法,本文继续介绍其他获取参数的方法. 文件上传 在web开发中文件上传是一个很常见的需求,下面我们来看一下基 ...

  9. 基于gin的golang web开发:访问mysql数据库

    web开发基本都离不开访问数据库,在Gin中使用mysql数据库需要依赖mysql的驱动.直接使用驱动提供的API就要写很多样板代码.你可以找到很多扩展包这里介绍的是jmoiron/sqlx.另外还有 ...

随机推荐

  1. Python-py2和py3读写文本区别

    python2和python3的区别? python 2  str             对应      python3 bytes python 2 uincode            对应   ...

  2. 卧槽!最新编程语言排名,Java 沦为老二。。

    2020 年 9 月刚过去,栈长看了下最新的 tiobe 编程语言榜,牛逼啊,C 语言居然登顶了,Java 下降 3 个点,沦为老二的位置. 数据来源TIOBE: https://www.tiobe. ...

  3. python文档下载

    网址记录:https://docs.python.org/3.6/

  4. 不会吧,这也行?iOS后台锁屏监听摇一摇

    目录 背景介绍 探索过程 其他 APP 有没有类似功能 系统提供的摇一摇回调能否满足 其他方法能否实现 利用 CoreMotion 框架,监听加速计原始数据 通过加速计监听摇一摇 控制器相关逻辑和代码 ...

  5. PHP的学习(提前学习了,业余爱好) (一)

    一个函数一个函数地堆 strstr()函数 在本地测试的时候,代码与显示如下 1.代码: <?php echo strstr("I love Shanghai!123",&q ...

  6. MeteoInfoLab脚本示例:地图投影

    在用axesm函数创建地图坐标系的时候可以指定地图投影(设置projinfo参数),地图投影可以通过projinfo函数来创建,里面的参数依据proj4投影字符串,可以参考此网页:http://rem ...

  7. MeteoInfo脚本示例:GrADS to netCDF

    这里给出一个将GrADS数据文件转为netCDF数据文件的脚本示例程序,其它格式数据转netCDF可以参考: #-------------------------------------------- ...

  8. selenium等待机制学习笔记

    转载至: https://blog.csdn.net/huilan_same/article/details/52544521 1. 强制等待 第一种也是最简单粗暴的一种办法就是强制等待sleep(x ...

  9. EfCore3的OwnedType会导致Sql效率问题

    最近主导了旗下某核心项目升级到EfCore3 由于之前Core2升级时候也踩过不少的坑很多东西都有规划和准备,整体上还是没出太大问题 但是最近突然发现efcore对于使用了ownedType的生成语句 ...

  10. centos8平台redis cluster集群添加/删除node节点(redis5.0.7)

    一,当前redis cluster的node情况: 我们的添加删除等操作都是以这个cluster作为demo cluster采用六台redis,3主3从 redis1 : ip: 172.17.0.2 ...