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. Hibernate4.3 HQL查询

    HQL:Hibernate专属语言,可以跨数据库 一.基本查询 1 public void testQuery(){ 2 Session session = HibernateUtils.getSes ...

  2. 「ExLucas」学习笔记

    「ExLucas」学习笔记 前置芝士 中国剩余定理 \(CRT\) \(Lucas\) 定理 \(ExGCD\) 亿点点数学知识 给龙蝶打波广告 Lucas 定理 \(C^m_n = C^{m\% m ...

  3. Azure Cosmos DB (一) 入门介绍

    一,引言 今天是国庆.中秋双节房价的第三天,今天抽时间分享一篇关于使用Azure 提供的一项NoSql 服务-----Azure Cosmos DB.就有人问了,我听说过 MongoDB.Redis ...

  4. matlab一个figure画多个子图,和多个figure画多个图。

    参考:https://blog.csdn.net/xiaotao_1/article/details/79024488 1,一个figure画多个子图: figure(10) % define fig ...

  5. linux下各种骚操作

    (备注:不定时更新) 1. ctrl+l  清屏快捷键,相当于clear 2. !+命令开头部分   执行最近执行的此条命令   ### 如!vi  编辑上一次用vi打开的文件, 3. echo $$ ...

  6. 创建自定义视图在Android矩阵效果画布教程

    介绍 下面是一个快速教程,教你如何在Android中创建自定义视图.自定义视图创建一个矩阵雨效果. 本教程发布在http://www.androidlearner.com/. 背景 下面是关于如何工作 ...

  7. 开始在Windows上开发Android

    介绍 鉴于您正在阅读这篇文章,您很可能已经知道android是什么了.可能.在科幻小说和电影中,机器人本质上是具有拟人化特征的机器人.还记得<星球大战>里的C-3PO吗?那<星际迷航 ...

  8. 如何检测ASP中的浏览器。NET与浏览器文件

    介绍 ASP.NET是一个用于使用Web表单.MVC.Web API和SignalR(这是官方定义)构建Web应用程序的高生产力框架.它是在.net框架上开发RESTful应用程序或使用HTML.CS ...

  9. vue 异步提交php 两种方式传值

    1.首先要在php的入口文件写上一条代码,允许异步提交 header("ACCESS-CONTROL-ALLOW-ORIGIN:*"); 2.在vue有两种方式将数据异步提交到ph ...

  10. linux网络收包过程

    记录一下linux数据包从网卡进入协议栈的过程,不涉及驱动,不涉及其他层的协议处理. 内核是如何知道网卡收到数据的,这就涉及到网卡和内核的交互方式: 轮询(poll):内核周期性的检查网卡,查看是否收 ...