gin: 用go-playground/validator校验参数,并返回自定义错误信息

一,安装第三方库

$ go get -u github.com/go-playground/validator/v10
go: downloading github.com/go-playground/validator/v10 v10.27.0
go: downloading github.com/gabriel-vasile/mimetype v1.4.10
go: downloading golang.org/x/crypto v0.33.0
go: downloading golang.org/x/crypto v0.42.0
go: downloading golang.org/x/sys v0.30.0
go: downloading golang.org/x/sys v0.36.0
go: downloading golang.org/x/net v0.44.0
go: upgraded github.com/gabriel-vasile/mimetype v1.4.3 => v1.4.10
go: upgraded github.com/go-playground/validator/v10 v10.20.0 => v10.27.0
go: upgraded golang.org/x/crypto v0.23.0 => v0.42.0
go: upgraded golang.org/x/net v0.25.0 => v0.44.0
go: upgraded golang.org/x/sys v0.29.0 => v0.36.0

二,代码

1,函数

//得到检验的报错信息
func GetValidateErrorMsg(u interface{}, err error) string {
	if err == nil { //如果为nil 说明校验通过
		return ""
	}
	invalid, ok := err.(*validator.InvalidValidationError) //如果是输入参数无效,则直接返回输入参数错误
	if ok {
		return "输入参数错误:" + invalid.Error()
	}
	validationErrs := err.(validator.ValidationErrors)  //断言是ValidationErrors
	for _, validationErr := range validationErrs {
		fieldName := validationErr.Field() //获取是哪个字段不符合格式
		typeOf := reflect.TypeOf(u)
		// 如果是指针,获取其属性
		if typeOf.Kind() == reflect.Ptr {
			typeOf = typeOf.Elem()
		}
		field, ok := typeOf.FieldByName(fieldName) //通过反射获取filed
		if ok {
			errorInfo := field.Tag.Get("label") // 获取field对应的reg_error_info tag值
			return fieldName + ":" + errorInfo           // 返回错误
		} else {
			return fieldName + ":" + validationErr.Error()
		}
	}
	return ""
}

2,controller

type MediaListReq struct {
	Cid        int  `form:"cid" json:"cid" binding:"required,gte=1,lte=100" label:"cid需要为1-100整数,请重新输入"`
	Bid        int  `form:"bid" json:"bid" binding:"required,min=2,max=10" label:"bid需要为2-10整数,请重新输入"`
	Did        string  `form:"did" json:"did" binding:"required,oneof=a b c" label:"did需要为a、b、c之一"`
}


//得到列表
func (ic *MediaController) List(c *gin.Context) {

	var req MediaListReq
	if err := c.ShouldBindQuery(&req); err != nil {
		fmt.Println("参数有错误:")
		fmt.Println(err)

		errMsg := global.GetValidateErrorMsg(req, err)
		//c.JSON(http.StatusBadRequest, gin.H{"err": errMsg,})
		global.NewResult(c).ErrorCode(500,errMsg,nil)
		return
	} else {
		fmt.Println("参数无错误:")
		fmt.Println(req.Cid)
		fmt.Println(req.Bid)
	}

	slides,err := dao.GetHomeSlides(c)
	if err != nil {
		global.NewResult(c).ErrorCode(500,"数据查询出错",nil)
		return
	}
	fmt.Print("slides:")
	fmt.Print(slides)
	for index, value := range slides {
		fmt.Printf("Index: %d, Value id: %d\n", index, value.Id)
	}

	var data = gin.H{
		"Title": "Gin 列表示例",
		"Message": "欢迎来到Gin 列表!",
	}
	c.HTML(200, "list.html", data)
}

三,测试效果

image

posted @ 2025-09-20 09:51  刘宏缔的架构森林  阅读(58)  评论(0)    收藏  举报