gin框架中,默认集成了数据效验包 validator,首先定义接收请求参数的结构体,在结构体中 定义指定的效验规则。
基本使用 
定义结构体 
实例一个登录接口
go
package main
import (
	"github.com/gin-gonic/gin"
	"net/http"
)
// Login 用户登录
func Login(ctx *gin.Context) {
	type TempData struct {
		Name     string `json:"username" binding:"required,max=2"`
		Password string `json:"password"`
	}
	temp := TempData{}
	if err := ctx.ShouldBind(&temp); err != nil {
		ctx.JSON(http.StatusBadRequest, ParamsNilError.WithMsg(err.Error()))
	}
}请求结果 
通httpClient请求接口
http
### 用户登录
// @no-log
POST http://localhost:8000/api/v1/user/login
Content-Type: application/json
{
  "username": "how2j"
}响应结果
http
POST http://localhost:8000/api/v1/user/login
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Date: Tue, 26 Nov 2024 05:39:20 GMT
Content-Length: 129
{
  "code": -1,
  "status": false,
  "message": "Key: 'TempData.Name' Error:Field validation for 'Name' failed on the 'max' tag",
  "data": null
}
响应文件已保存。
> 由于禁用了文件登录,无法显示响应
Response code: 400 (Bad Request); Time: 7ms (7 ms); Content length: 129 bytes (129 B)错误信息自定义 
添加自定义错误信息tag 
自定义tag规则: [tag]Msg: message
go
type TempData struct {
		Name     string `json:"username" binding:"required,max=2" requiredMsg:"用户名不能为空"`
		Password string `json:"password"`
	}添加错误消息处理方法 
创建/utils/request.go文件, ctx.ShouldBind(&temp)方法产生的error中,数据校验失败返回的是validator.ValidationErrors类型,根据这个类型进行错误消息的处理。
一、首先进行错误类型判断
go
// ValidateErrorMsg 消息类型
type ValidateErrorMsg map[string]string
func GetErrorMsg(err error, structure interface{}) string {
    // 如果err是validator.ValidationErrors类型,获取第一个错误信息
    if errors.As(err, &validationErrors) && len(validationErrors) > 0 {
        // ...processing
    }
}二、 使用反射机制来获取结构体中自定义的tag信息
- 使用 reflect.TypeOf() 函数获取结构体的类型信息
 - 通过FieldByName找到指定结构体字段信息
 - filed.Tag.Get方法获取tag信息
 
go
// ValidateErrorMsg 消息类型
type ValidateErrorMsg map[string]string
func GetErrorMsg(err error, structure interface{}) string {
// 如果err是validator.ValidationErrors类型,获取第一个错误信息
if errors.As(err, &validationErrors) && len(validationErrors) > 0 {
s := reflect.TypeOf(structure)
errMsg := validationErrors[0]
filed, _ := s.FieldByName(errMsg.Field()) // 获取效验失败字段信息
errText := filed.Tag.Get(errMsg.Tag() + "Msg") // 获取自定义信息
}
}三、完整代码
go
package utils
import (
	"errors"
	"github.com/go-playground/validator/v10"
	"reflect"
)
// ValidateErrorMsg 消息类型
type ValidateErrorMsg map[string]string
func GetErrorMsg(err error, structure interface{}) string {
	var validationErrors validator.ValidationErrors
	// 如果err是validator.ValidationErrors类型,获取第一个错误信息
	if errors.As(err, &validationErrors) && len(validationErrors) > 0 {
		s := reflect.TypeOf(structure)
		errMsg := validationErrors[0]
		filed, _ := s.FieldByName(errMsg.Field())
		errText := filed.Tag.Get(errMsg.Tag() + "Msg")
		// 如果没有自定义消息,返回错误成员本身的错误信息
		if errText == "" {
			return err.Error()
		}
		return errText
	}
	// 其他类型的错误直接返回错误信息
	return err.Error()
}自定义效验规则 
可以查看Gin-自定义验证器文档
创建validator.go文件
go
func InitValidator() {
    if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
        // 自定义验证器注册
        _ = v.RegisterValidation("mobile", validateMobile)
    }
}
// 校验手机号
func validateMobile(fl validator.FieldLevel) bool {
    mobile := fl.Field().String()
    // 手机号为空则不验证,这里只验证有值的
    if mobile == "" {
        return true
    }
    ok, _ := regexp.MatchString(`^1[3-9]\d{9}$`, mobile)
    return ok
}在 main.go 文件中注册
go
func main() {
    // 注册验证器
    validator.InitValidator()
}