gin自定义验证器和翻译器
# gin 自定义验证器和翻译响应内容
# validator 翻译文档地址
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-playground/locales/zh"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
"github.com/go-playground/validator/v10/translations/en"
zh2 "github.com/go-playground/validator/v10/translations/zh"
"net/http"
"reflect"
"strings"
)
type LoginReq struct {
User string `form:"user" json:"user" xml:"user" binding:"required,min=3,max=10"`
Password string `form:"password" json:"password" xml:"password" binding:"required"`
}
type SignupReq struct {
Age uint8 `json:"age" binding:"gte=1,lte=130"`
Name string `json:"name" binding:"required,min=3"`
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required"`
RePassword string `json:"re_password" binding:"required,eqfield=Password"` // 跨字段验证
}
var trans ut.Translator
func removeTopStruct(fields map[string]string) map[string]string {
rsp := map[string]string{}
for field, err := range fields {
rsp[field[strings.Index(field, ".")+1:]] = err
}
return rsp
}
func InitTrans(locale string) (err error) {
// 修改 gin 的 validator 引擎属性,实现定制
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
// 注册一个获取 json 的 tag 的自定义方法
v.RegisterTagNameFunc(func(field reflect.StructField) string {
name := strings.SplitN(field.Tag.Get("json"), ",", 2)[0]
if name == "-" {
return ""
} else {
return name
}
})
zhCn := zh.New() // 中文翻译器
uni := ut.New(zhCn, zhCn)
trans, ok = uni.GetTranslator(locale)
if !ok {
return fmt.Errorf("uni.GetTranslator(%s)", locale)
}
switch locale {
case "zh":
err := zh2.RegisterDefaultTranslations(v, trans)
if err != nil {
return err
}
case "en":
err := en.RegisterDefaultTranslations(v, trans)
if err != nil {
return err
}
default:
err := zh2.RegisterDefaultTranslations(v, trans)
if err != nil {
return err
}
}
return
}
return
}
func main() {
if err := InitTrans("zh"); err != nil {
fmt.Println(err.Error())
fmt.Println("初始化翻译器错误")
return
}
r := gin.Default()
r.POST("/login", func(c *gin.Context) {
var loginReq LoginReq
err := c.ShouldBind(&loginReq)
if err != nil {
errs, ok := err.(validator.ValidationErrors)
if !ok {
c.JSON(http.StatusOK, gin.H{
// 返回原错误
"msg": err.Error(),
})
}
c.JSON(http.StatusBadRequest, gin.H{
"error": removeTopStruct(errs.Translate(trans)), // 处理错误提示前面的结构体名称
})
return
}
c.JSON(http.StatusOK, gin.H{
"msg": "登录成功",
})
})
r.POST("/register", func(c *gin.Context) {
var signupReq SignupReq
err := c.ShouldBind(&signupReq)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"msg": "注册成功",
})
})
err := r.Run()
if err != nil {
fmt.Println(err.Error())
return
}
}
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
编辑 (opens new window)
上次更新: 2023/02/11, 15:50:41