使用ShouldBind示例

1
2
3
4
5
6
7
8
9
10
11
// 定义一个结构体绑定请求数据
type RequestUserLogin struct {
Username string `form:"username" json:"username" xml:"username" binding:"required"`
Password string `form:"password" json:"password" xml:"password" binding:"required"`
}

data := new(RequestUserLogin)
if err := c.ShouldBind(data); err != nil {
c.JSON(http.StatusForbidden, gin.H{"error": err.Error()})
return
}

得到的错误提示大概时这样子的

1
2
3
{
"error":"Key: 'RequestAdminUserLogin.Password' Error:Field validation for 'Password' failed on the 'required' tag"
}

该怎么样给api提供一个友好的错误信息呢?

  1. 首先,判断ShouldBind返回的底层类型是什么

    1
    fmt.Println(reflect.TypeOf(err))

    打印的信息是:validator.ValidationErrors

  2. 让我们看看validator.ValidationErrors究竟是什么

    通过查看源码我们可以看到:

    1
    type ValidationErrors []FieldError

    原来它是一个FieldError类型的切片;

  3. 查看FieldError类型

    源码上是这样子说的:FieldError包含获取错误信息的所有方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // FieldError contains all functions to get error details
    type FieldError interface {

    Tag() string

    ActualTag() string

    Namespace() string

    StructNamespace() string

    Field() string

    StructField() string

    Value() interface{}

    Param() string

    Kind() reflect.Kind

    Type() reflect.Type

    Translate(ut ut.Translator) string
    }
  4. 让我打印下FieldError看下吧

    1
    fmt.Println(field.Tag(), field.ActualTag(), field.Namespace(), field.StructNamespace(), field.Field(), field.StructField(), field.Value(), field.Param(), field.Kind(), field.Type())

    得到的结果是:

    1
    required required RequestAdminUserLogin.Password RequestAdminUserLogin.Password Password Password "" string string

让我们自定义一个友好的错误信息吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 定义一个结构体绑定请求数据
type RequestUserLogin struct {
Username string `form:"username" json:"username" xml:"username" binding:"required"`
Password string `form:"password" json:"password" xml:"password" binding:"required"`
}

func getParamError(err validator.ValidationErrors) map[string]string {
result := make(map[string]string, 0)
for _, v := range err {
if field, ok := v.(validator.FieldError); ok {
result[field.Field()] = field.Tag()
}
}
return result
}

data := new(RequestUserLogin)
if err := c.ShouldBind(data); err != nil {
result := getParamError(err.(validator.ValidationErrors))
c.JSON(http.StatusForbidden, gin.H{"error": result})
return
}

返回的结果是:

1
2
3
4
5
{
"error": {
"Password": "required"
}
}

现在,你可以通过getParamError自由自在的返回你想要的错误信息了