gin自定義驗證器&轉化中文

liaosp發表於2021-07-28

在這裡插入圖片描述

使用gin 自帶 繫結驗證引數返回的是亂的英文,對於國人來說看起來不是特別友好

{
  "message": "Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'required' tag\nKey: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'required' tag"
}

validator 翻譯成中文

新建檔案 validator

package validator

//gin > 1.4.0

//將驗證器錯誤翻譯成中文

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() {
    //註冊翻譯器
    zh := zh.New()
    uni = ut.New(zh, zh)

    trans, _ = uni.GetTranslator("zh")

    //獲取gin的校驗器
    validate := binding.Validator.Engine().(*validator.Validate)
    //註冊翻譯器
    zh_translations.RegisterDefaultTranslations(validate, trans)
}

//Translate 翻譯錯誤資訊
func Translate(err error) map[string][]string {

    var result = make(map[string][]string)

    errors := err.(validator.ValidationErrors)

    for _, err := range errors{
        result[err.Field()] = append(result[err.Field()], err.Translate(trans))
    }
    return result
}

在main 中初始化

    validator.Init()

控制器中:

package api

import (
    "github.com/gin-gonic/gin"
    "yibage-api/validator"
)



type Booking struct {
    CheckIn  string `form:"check_in"  binding:"required"`
    CheckOut string`form:"check_out"  binding:"required"`
}

func Test(c *gin.Context) {

    var b Booking
    err := c.BindQuery(&b);
    if err == nil {
        c.JSON(200, gin.H{"message": "Success"})
        return;
    } else {
        c.JSON(200, gin.H{"message": validator.Translate(err)})
        return;
    }
}

上面用到了 在validator 中 的翻譯 validator.Translate(err)

效果:

{
  "message": {
    "CheckIn": [
      "CheckIn為必填欄位"
    ],
    "CheckOut": [
      "CheckOut為必填欄位"
    ]
  }
}

自定義引數驗證器

package main

import (
    "net/http"
    "reflect"
    "time"

    "github.com/gin-gonic/gin"
    "github.com/gin-gonic/gin/binding"
    "gopkg.in/go-playground/validator.v8"
)

// Booking contains binded and validated data.
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"`
}

func bookableDate(
    v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
    field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
) bool {
    if date, ok := field.Interface().(time.Time); ok {
        today := time.Now()
        if today.Year() > date.Year() || today.YearDay() > date.YearDay() {
            return false
        }
    }
    return true
}

func main() {
    route := gin.Default()

    if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
        v.RegisterValidation("bookabledate", bookableDate)
    }

    route.GET("/bookable", getBookable)
    route.Run(":8085")
}

func getBookable(c *gin.Context) {
    var b Booking
    if err := c.ShouldBindWith(&b, binding.Query); err == nil {
        c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
    } else {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    }
}

參考:www.kancloud.cn/shuangdeyu/gin_boo...

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章