gin框架使用goframe框架的gvalid数据校验组件
前言
gin框架自带了go-playground/validator这个数据校验组件,但对国内的使用习惯来说不太好用,还是国产goframe框架的gvalid数据校验组件更加适合中国宝宝。
看了一下goframe社区也有这方面的融合先驱,但用的方法是封装了一个方法,不太优雅。看了一下gin源码,他这块是用接口实现的,也就说是可以自定义校验方法的。
开干
1. 安装gin和gvalid
go get -u github.com/gin-gonic/gin
go get github.com/gogf/gf/v2/util/gvalid
2. 实现StructValidator接口
该接口位于binding/binding.go:53,gin框架自带的default_validator既使用go-playground/validator实现了这个接口。
代码如下:
package validator
import (
"context"
"github.com/gin-gonic/gin/binding"
"github.com/gogf/gf/v2/util/gvalid"
"reflect"
"sync"
)
type GfValidator struct {
once sync.Once
validate *gvalid.Validator
}
func (v *GfValidator) ValidateStruct(obj any) error {
if obj == nil {
return nil
}
value := reflect.ValueOf(obj)
switch value.Kind() {
case reflect.Ptr:
return v.ValidateStruct(value.Elem().Interface())
case reflect.Struct:
return v.validateStruct(obj)
case reflect.Slice, reflect.Array:
// 这里如果多个错误,会一并返回,如果只需要第一个错误,稍微改造就可以
count := value.Len()
validateRet := make(binding.SliceValidationError, 0)
for i := 0; i < count; i++ {
if err := v.ValidateStruct(value.Index(i).Interface()); err != nil {
validateRet = append(validateRet, err)
}
}
if len(validateRet) == 0 {
return nil
}
return validateRet
default:
return nil
}
}
func (v *GfValidator) Engine() any {
v.lazyInit()
return v.validate
}
func (v *GfValidator) lazyInit() {
v.once.Do(func() {
v.validate = gvalid.New()
})
}
func (v *GfValidator) validateStruct(obj any) error {
v.lazyInit()
return v.validate.Data(obj).Run(context.Background())
}
3. 绑定新的校验组件
binding.Validator = new(validator.GfValidator)
4. 完事儿,测试一下
package main
import (
"gin-validator/internal/validator"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"net/http"
)
type BizReq struct {
Account string `v:"required#"`
Password string `v:"required|same:Password2"`
Password2 string `v:"required"`
}
func main() {
r := gin.Default()
// 绑定新的校验组件
binding.Validator = new(validator.GfValidator)
// 弄个接口测试一下
r.POST("/ping", func(c *gin.Context) {
var req BizReq
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}
老铁,没毛病,使用习惯和原生一样,但错误提示更加适合中国宝宝了
可能有老铁会问了,这又加载了gf框哒,会不会把项目搞大了呀,不用担心哈,go编译时按需编译的
本作品采用《CC 协议》,转载必须注明作者和本文链接
go-playground/validator 这个包也有语言包,不过用起来确实不顺手,语言包翻译不太好用,想自定义又麻烦
中文怎么配置的