欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Gin框架自帶參數(shù)校驗的使用詳解

 更新時間:2023年09月19日 10:53:52   作者:uccs  
這篇文章主要為大家詳細介紹了如何使用Gin框架自帶的參數(shù)校驗,文中的示例代碼講解詳細,具有一定的學(xué)習(xí)價值,感興趣的小伙伴可以了解下

gin 框架內(nèi)置參數(shù)驗證,寫在 binging tag 中,如下所示:

type Tag struct {
  ID   int32  `json:"id" binding:"required"`
  Name string `json:"name" binding:"required"`
}

這個驗證器是由 validator 提供的,文檔

常用的操作符:

  • ,:且,多個驗證之間同時滿足
  • |:或,滿足其中一個
  • -:跳過驗證
  • =:等于

例子來源于官方文檔:

type User struct {
  FirstName      string     `binding:"required"`
  LastName       string     `binding:"required"`
  Age            uint8      `binding:"gte=0,lte=130"`
  Email          string     `binding:"required,email"` // 驗證是否是一個有效的 email 地址
  Gender         string     `binding:"oneof=male female prefer_not_to` // oneof 表示只能是其中之一 可以用 eq=male|eq=female|eq=prefer_not_to 代替
  FavouriteColor string     `binding:"iscolor"`                // iscolor 表示是否是一個有效的顏色值
  Addresses      []*Address `binding:"required,dive,required"` // dive 對嵌套結(jié)構(gòu)體進行遞歸驗證
}
type Address struct {
  Street string `binding:"required"`
  City   string `binding:"required"`
  Planet string `binding:"required"`
  Phone  string `binding:"required"`
}

在我們?nèi)粘V袝?jīng)常做手機號驗證,但是官方只有一個 e164 的驗證,e164 是國際通用標準(要加區(qū)號),就不太符合國內(nèi)用戶

這就需要自定義驗證器 mobile,根據(jù)官網(wǎng)提供的例子,實現(xiàn)它也是比較簡單的

自定義驗證器

首先定義一個 ValidateMobile 方法

import (
  "regexp"
  "github.com/go-playground/validator/v10"
)
func ValidateMobile(fl validator.FieldLevel) bool {
  mobile := fl.Field().String()
  ok, _ := regexp.MatchString(`^1([38][0-9]|14[579]|5[^4]16[6]|7[1-35-8]|9[189])\d{8}$`, mobile) // 用正則去匹配
  return ok
}

將方法注冊到 validator

import (
  "github.com/gin-gonic/gin/binding"
)
// 從 gin 中獲取到 validator 驗證器,然后注冊 mobile
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
  _ = v.RegisterValidation("mobile", myvalidator.ValidateMobile)
}

自定義驗證器就定義好了,使用的時候就可以這樣寫了

type User struct {
  Name    string `json:"name" binding:"required"`
  Mobile  string `json:"mobile" binding:"required,mobile"`
}

錯誤信息翻譯

validator 默認錯誤信息是英文,如果需要翻譯成中文,自己做轉(zhuǎn)換:

  • 跳過 json tag- 的字段
  • 實例化 zhen 翻譯包
  • 初始化翻譯器
  • 注冊翻譯器
  • 調(diào)用 InitTrans,傳入 zh 或者 en 即可

具體代碼如下:

import (
  "fmt"
  "mxshop_api/order_web/global"
  "reflect"
  "strings"
  "github.com/gin-gonic/gin/binding"
  "github.com/go-playground/locales/en"
  "github.com/go-playground/locales/zh"
  "github.com/go-playground/validator/v10"
  ut "github.com/go-playground/universal-translator"
  en_translations "github.com/go-playground/validator/v10/translations/en"
  zh_translations "github.com/go-playground/validator/v10/translations/zh"
)
func InitTrans(local string) (err error) {
  // 修改 gin 中 validator 實現(xiàn)定制
  if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
    // 將 json tag 作為字段名
    v.RegisterTagNameFunc(func(fld reflect.StructField) string {
      name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
      // 如果 json tag 為 - 則不處理
      if name == "-" {
        return ""
      }
      return name
    })
    zhT := zh.New()
    enT := en.New()
    // 第一個參數(shù)是備用的語言環(huán)境,后面的參數(shù)是應(yīng)該支持的語言環(huán)境
    uni := ut.New(enT, zhT, enT)
    // 初始化翻譯器
    global.Trans, ok = uni.GetTranslator(local)
    if !ok {
      return fmt.Errorf("uni.GetTranslator(%s)", local)
    }
    switch local {
    case "en":
      en_translations.RegisterDefaultTranslations(v, global.Trans)
    case "zh":
      zh_translations.RegisterDefaultTranslations(v, global.Trans)
    default:
      en_translations.RegisterDefaultTranslations(v, global.Trans)
    }
    return
  }
  return
}

使用:

if err := initialize.InitTrans("zh"); err != nil {
  panic(err)
}

這個翻譯器只能夠翻譯內(nèi)置的錯誤信息,自定義的驗證器需要自己翻譯

比如我們上面定義的 mobile 驗證器,如果驗證失敗,返回的錯誤信息需要我們自己翻譯

參照官方例子,如下代碼:

// 四個參數(shù)
// 需要翻譯的字段名 翻譯器實例 翻譯方法 返回錯誤的信息
_ = validator.RegisterTranslation("mobile", global.Trans, func(ut ut.Translator) error {
  // 翻譯的內(nèi)容
  return ut.Add("mobile", "{0} 非法的手機號碼!", true)
}, func(ut ut.Translator, fe validator.FieldError) string {
  // fe.Field() 獲取到的是字段名,而不是 json tag
  t, _ := ut.T("mobile", fe.Field())
  return t
})

這樣就可以翻譯自定義的驗證器了,最終代碼如下:

// 注冊驗證器
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
  _ = v.RegisterValidation("mobile", myvalidator.ValidateMobile)
  _ = v.RegisterTranslation("mobile", global.Trans, func(ut ut.Translator) error {
    return ut.Add("mobile", "{0} 非法的手機號碼!", true) // see universal-translator for details
  }, func(ut ut.Translator, fe validator.FieldError) string {
    t, _ := ut.T("mobile", fe.Field())
    return t
  })
}

格式化返回信息

validator 默認返回的錯誤信息是 json tag,這不是我們希望的

我們希望拋出去的錯誤是結(jié)構(gòu)化的

  • 使用 shouldBindJSON 將參數(shù)接寫到對應(yīng)的結(jié)構(gòu)體中
  • 如果解析失敗,則斷言這個錯誤為 validator.ValidationErrors
  • 如果斷言成功,則將錯誤進行翻譯
  • 去掉結(jié)構(gòu)體中的前綴,并生成一個 map
  • 將這個 map 拋出去

最終代碼如下:

if err := ctx.ShouldBindJSON(&bannerForm); err != nil {
  HandleValidatorError(ctx, err)
  return
}
func HandleValidatorError(c *gin.Context, err error) {
  errs, ok := err.(validator.ValidationErrors)
  if !ok {
    c.JSON(http.StatusOK, gin.H{
      "msg": err.Error(),
    })
  }
  c.JSON(http.StatusBadRequest, gin.H{
    "error": removeTopStruct(errs.Translate(global.Trans)),
  })
  return
}
func removeTopStruct(fields map[string]string) map[string]string {
  rsp := map[string]string{}
  for field, err := range fields {
    // 去掉結(jié)構(gòu)體中的前綴 {User.mobile: "mobile 非法的手機號碼!"}
    rsp[field[strings.Index(field, ".")+1:]] = err
  }
  return rsp
}

錯誤類型在文檔中有說明type FieldError

  • Tag():得到的是你寫的 requiremobile
  • Field():結(jié)構(gòu)體中定義的字段名
  • Translate():翻譯

總結(jié)

validator 能夠滿足我們?nèi)粘5男枨螅?/p>

  • 對嵌套結(jié)構(gòu)體進行遞歸驗證
  • 自定義驗證器
  • 錯誤信息翻譯
  • 格式化返回信息

到此這篇關(guān)于Gin框架自帶參數(shù)校驗的使用詳解的文章就介紹到這了,更多相關(guān)Gin參數(shù)校驗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Kotlin編程基礎(chǔ)語法編碼規(guī)范

    Kotlin編程基礎(chǔ)語法編碼規(guī)范

    這篇文章主要為大家介紹了Kotlin編程條件控制示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • GO語io包的常用接口

    GO語io包的常用接口

    這篇文章主要介紹了GO語io包的常用接口,分析了GO語言接口的概念與功能,并實例列舉了幾個最常用的接口的用法,具有一定的參考借鑒價值,需要的朋友可以參考下
    2014-12-12
  • go語言優(yōu)雅地處理error工具及技巧詳解

    go語言優(yōu)雅地處理error工具及技巧詳解

    這篇文章主要為大家介紹了go語言優(yōu)雅地處理error工具及技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • 重學(xué)Go語言之變量與常量的聲明與使用詳解

    重學(xué)Go語言之變量與常量的聲明與使用詳解

    變量、常量的聲明與使用是掌握一門編程語言的基礎(chǔ),在這篇文章中,小編就來帶大家學(xué)習(xí)一下Go語言是怎么樣聲明和使用變量與常量吧
    2023-03-03
  • Golang文件讀寫操作詳情

    Golang文件讀寫操作詳情

    這篇文章主要介紹了Golang文件讀寫操作詳情,文件是數(shù)據(jù)源(保存數(shù)據(jù)的地方)的一種,文件最主要的作用就是保存數(shù)據(jù),文件在程序中是以流的形式來操作的,更多詳細內(nèi)容需要的朋友可以參考一下
    2022-07-07
  • Go語言變量創(chuàng)建的五種方法

    Go語言變量創(chuàng)建的五種方法

    這篇文章主要介紹了Go語言五種變量創(chuàng)建的方法,本文給大家提到了匿名變量的優(yōu)點,通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2020-02-02
  • 一文詳解在Go中如何使用Viper來管理配置

    一文詳解在Go中如何使用Viper來管理配置

    Viper 是一個功能齊全的 Go 應(yīng)用程序配置庫,支持很多場景。在本文中,我們將深入探討 Viper 的各種用法和使用場景,以幫助讀者更好地了解和使用 Viper 來管理應(yīng)用程序配置,感興趣的同學(xué)可以參考閱讀
    2023-05-05
  • Golang并發(fā)編程之調(diào)度器初始化詳解

    Golang并發(fā)編程之調(diào)度器初始化詳解

    這篇文章主要為大家詳細介紹了Golang并發(fā)編程中關(guān)于調(diào)度器初始化的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2023-03-03
  • Golang中的sync包的WaitGroup操作

    Golang中的sync包的WaitGroup操作

    這篇文章主要介紹了Golang中的sync包的WaitGroup操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Golong字符串拼接性能優(yōu)化及原理介紹

    Golong字符串拼接性能優(yōu)化及原理介紹

    最近在做性能優(yōu)化,有個函數(shù)里面的耗時特別長,看里面的操作大多是一些字符串拼接的操作,而字符串拼接在 golang 里面其實有很多種實現(xiàn),下面這篇文章主要給大家介紹了關(guān)于Golang語言如何高效拼接字符串的相關(guān)資料,需要的朋友可以參考下
    2023-04-04

最新評論