• 基于gin的golang web开发:模型验证


    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
    Key: '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开发:模型验证

  • 相关阅读:
    自动化:Appium运行成功,取得一个小的胜利
    调优案例1
    HTTP请求方式中8种请求方法(简单介绍)
    Java中基本类型和引用类型(简单介绍)
    @WebListener 注解方式实现监听(eclipse和idea)
    Git免密码提交
    在idea配置jetty和创建(包、文件)javaWeb以及Servlet简单实现
    emmet工具使用和技巧
    Markdown基本语法总结
    viewport原理和使用和设置移动端自适应的方法(移动适应电脑)
  • 原文地址:https://www.cnblogs.com/huaface/p/13925542.html
Copyright © 2020-2023  润新知