type SignUserInfo struct { // 添加验证器 常用的 此处 uniqueName是一个自定义的验证器 Name string`json:"name" binding:"required,uniqueName" msg:"昵称不能为空也不能重复"`// 用户名 Age int`json:"age" binding:"lt=100,gt=0" msg:"年龄不符合要求"`// 年龄 }
// 简单写,直接用一个字符串数组 实际开发需要存储用户信息的数据库然后到数据库中查找昵称是否重复 var nameList = []string{"张三", "李四", "王五"}
func _GetValidMsg(err error, user SignUserInfo)string { // 将err接口断言为具体类型 if errs, ok := err.(validator.ValidationErrors); ok { getObj := reflect.TypeOf(&user) fmt.Println("类型为:", getObj)
// 断言成功 for _, e := range errs { // 遍历每一个错误信息 报错信息可能有多个 // 根据报错字段名,获取结构体的具体字段 if f, exits := getObj.Elem().FieldByName(e.Field()); exits { msg := f.Tag.Get("msg") fmt.Println(msg) return msg } } } return""// 没有检查到验证器错误则返回空 }
// 函数原型为 func(fl FieldLevel) bool func _nameCheck(fl validator.FieldLevel)bool { // 遍历用户信息列表 实际应到数据库中查询,这里只是简单模拟 for _, nameStr := range nameList { // 断言 name := fl.Field().Interface().(string)
if nameStr == name { returnfalse } } returntrue }
funcmain() { router := gin.Default()
if v, ok := binding.Validator.Engine().(*validator.Validate); ok { // 注册uniqueName验证器,其自定义验证功能通过_nameCheck函数来实现 err := v.RegisterValidation("uniqueName", _nameCheck) if err != nil { return } }
router.POST("/custom-check", func(c *gin.Context) { fmt.Println("访问...") var user SignUserInfo err := c.ShouldBindJSON(&user) // 返回error信息,不报错则返回空 if err != nil { customErr := _GetValidMsg(err, user) c.JSON(http.StatusBadRequest, gin.H{"msg": customErr}) return }