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 数据处理全家桶(Memcached篇)

    1. 前言 本篇文章继续继续另外一种比较常用的数据存储方式:Memcached Memcached:一款高性能分布式内存对象缓存系统,通过 内存缓存,以减少数据库的读取,从而分担数据库的压力,进而提高 ...

  2. VPS教程:搭建个人网盘教程—kodexplorer

    kodexplorer网盘系统.Kodexplorer,也叫芒果云.可道云.kodcloud,总之名字改了不少.但其本身作为一个网盘文件系统,还是有很多可圈可点的地方. seafile.h5ai.ko ...

  3. c++ 在window下创建窗口的基本步骤

    1. WinMain 函数的定义: 2. 创建一个窗口 2.1 设计一个窗口类 WNDCLASS 2.2 注册窗口类 2.3 创建窗口 2.4 显示及更新窗口 3. 进行消息循环 BOOL GetMe ...

  4. 【题解】SP1811 LCS - Longest Common Substring

    \(\color{purple}{Link}\) \(\text{Solution:}\) 题目要求找到两个串的最长公共子串.\(LCP\) 我们将两个串中间和末尾插入终止符,并弄到一棵后缀树上去. ...

  5. Vue3实战系列:结合 Ant-Design-of-Vue 实践 Composition API

    Vue 3 出来之后,很多人有如下想法,"又要学新东西啦"."我学不动了"等等. 但是事物总有它的两面性,前端知识更新的很快,利好勤奋好学的同学.计算机行业的迭 ...

  6. devops-jenkins基于角色的权限管理RBAC

    一. devops-jenkins基于角色的权限管理RBAC 1 安装角色的rbac角色管理  1.1) 点击系统管理 1.2) 选择插件管理 1.3) 选择可选插件,输入role搜索 1.4) 选择 ...

  7. Python+Appium自动化测试(9)-自动选择USB用于传输文件(不依赖appium对手机页面元素进行定位)

    一,问题 app自动化测试使用Android真机连接电脑时,通常会遇到两种情况: 1.测试机连接电脑会弹窗提示USB选项,选择USB用于"传输文件",有些手机不支持设置默认USB选 ...

  8. day30 Pyhton 面向对象 反射

    @property # 例1 - 1 (某一个属性如果是通过计算得来的,那么计算的过程写在方法里,把这个方法伪装成属性) from math import pi # class Circle: # d ...

  9. Jenkins+pytest+Allure搭建自动化测试

    持续集成(CONTINUOUS INTEGRATION) 在CI环境中,开发人员将会频繁地向主干提交代码.这些新提交的代码在最终合并到主干前,需要经过编译和自动化测试流进行验证. 持续交付(CONTI ...

  10. Spring mvc文件上传实现

    Spring mvc文件上传实现 jsp页面客户端表单编写 三个要素: 1.表单项type="file" 2.表单的提交方式:post 3.表单的enctype属性是多部分表单形式 ...