使用go-playground/validator实现请求参数验证并输出中文错误信息
时间:2021-11-12 作者:smarteng 分类: Go语言
实现目标
go-playground/validator
原始的参数验证错误信息为英文字符串,很不友好。
在网上找到了这篇文章,解决了大部分问题。但是返回的错误信息没有分字段,且没有真实字段名,对前端来说不友好。
最后自己动手稍作改造,先看看最后实现的结果:
请求数据类型:
//PageInfo 分页请求数据结构
type PageInfo struct {
Page int `json:"page" validate:"required,min=1" label:"页码"`
PageSize int `json:"pageSize" validate:"required,max=100" label:"每页大小"`
}
错误请求参数响应 json
如下:
{
"code": -1,
"msg": "请求参数验证失败",
"errors": {
"Page": "页码为必填字段",
"PageSize": "每页大小为必填字段"
}
}
安装扩展包
github.com/go-playground/locales
github.com/go-playground/universal-translator
github.com/go-playground/validator/v10
添加 validator
服务包
validator.go
:
package validator
import (
"os"
"reflect"
"fmt"
"github.com/go-playground/locales/zh"
translator "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
zh_translations "github.com/go-playground/validator/v10/translations/zh"
)
//Validate 验证器
var Validate *validator.Validate
var trans translator.Translator
func init() {
uni := translator.New(zh.New())
trans, _ = uni.GetTranslator("zh")
Validate = validator.New()
//注册一个函数,获取struct tag里自定义的label作为字段名--重点1
Validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
label := fld.Tag.Get("label")
if label == "" {
return fld.Name
}
return label
})
//注册翻译器
err := zh_translations.RegisterDefaultTranslations(Validate, trans)
if err != nil {
fmt.Println(err.Error())
os.Exit(0) //无法初始化验证器,退出应用
}
}
//Translate 翻译工具
func Translate(err error, s interface{}) map[string]string {
r := make(map[string]string)
t := reflect.TypeOf(s).Elem()
for _, err := range err.(validator.ValidationErrors) {
//使用反射方法获取struct种的json标签作为key --重点2
var k string
if field, ok := t.FieldByName(err.StructField()); ok {
k = field.Tag.Get("json")
}
if k == "" {
k = err.StructField()
}
r[k] = err.Translate(trans)
}
return r
}
使用方法
//PageInfo 分页请求数据结构
type PageInfo struct {
Page int `json:"page" validate:"required,min=1" label:"页码"`
PageSize int `json:"pageSize" validate:"required,max=100" label:"每页大小"`
}
//Errors 错误响应
type Errors struct {
Code int `json:"code"`
Msg string `json:"msg"`
Errors interface{} `json:"errors"`
}
…………
func Hello(c *gin.Context) {
var pageInfo PageInfo
_ = c.ShouldBind(&pageInfo) //这里是gin的绑定参数方法,请改成自己的
err := validator.Validate.Struct(pageInfo) //注意导入validator包
if err != nil {
r := validator.Translate(err,pageInfo)
c.JSON(http.StatusBadRequest, Errors{
Code: -1,
Msg: "请求参数验证失败",
Errors: r,
})
return
}
…………
}
标签: validator