Go Gin框架下struct tag校验返回自定义错误消息实现咨询
Gin框架struct参数校验自定义错误返回实现方案
Gin v1.17+默认使用github.com/go-playground/validator/v10作为底层校验库,默认返回的错误本质是结构化的校验错误类型,你只需对错误做类型断言和格式转换即可实现需求,具体实现如下:
步骤1:定义错误映射规则与通用转换函数
先声明校验标签对应的提示信息映射,再编写通用方法将默认校验错误转换为你需要的键值对格式:
import ( "net/http" "reflect" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "github.com/go-playground/validator/v10" ) // 校验tag对应错误提示映射,可根据业务需求扩展 var tagMsgMap = map[string]string{ "required": "This field is required", "email": "Invalid email", "gte": "The value is too small", "lte": "The value is too large", "iscolor": "Invalid color format", } // parseValidationErrors 转换校验错误为指定的键值对格式 // 参数err为校验返回的错误,target为绑定参数的struct指针 func parseValidationErrors(err error, target interface{}) map[string]string { errRes := make(map[string]string) // 先断言错误是否为validator的校验错误类型 validationErrs, ok := err.(validator.ValidationErrors) if !ok { // 非校验类错误(比如JSON格式错误)可单独处理 errRes["common"] = "Invalid request parameters" return errRes } // 获取struct的类型信息,用于读取字段的json tag structType := reflect.TypeOf(target).Elem() for _, validationErr := range validationErrs { // 获取校验失败的struct字段信息 field, exist := structType.FieldByName(validationErr.StructField()) if !exist { errRes[validationErr.StructField()] = validationErr.Error() continue } // 读取json tag作为返回的错误key,没有json tag则用struct字段名 jsonKey := field.Tag.Get("json") if jsonKey == "" { jsonKey = validationErr.StructField() } // 读取对应tag的错误提示,没有匹配的tag则返回默认错误 msg, exist := tagMsgMap[validationErr.Tag()] if !exist { msg = validationErr.Error() } errRes[jsonKey] = msg } return errRes }
步骤2:修改路由Handler的错误处理逻辑
将原错误处理逻辑替换为调用上述转换方法即可:
var u User if err := c.ShouldBindWith(&u, binding.Query); err == nil { c.JSON(http.StatusOK, gin.H{"message": "Good Job"}) } else { // 调用转换方法生成自定义格式错误 customErr := parseValidationErrors(err, &u) c.JSON(http.StatusBadRequest, gin.H{"errors": customErr}) }
注意事项
- 你给出的期望返回示例中
errors用了数组括号[]属于笔误,键值对结构应使用对象括号{},上述代码返回的是符合JSON规范的结构 - 如果需要中文错误提示,直接修改
tagMsgMap中的value值即可 - 新增自定义校验规则后,只需在
tagMsgMap中新增对应tag和提示信息即可生效
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

