1.validator简介
validator是一个开源的验证器包,可以快速校验输入信息是否符合自定规则。源码地址: https://github.com/go-playground/validator
本地开发安装库:
go get github.com/go-playground/validator
2.常用示例
例如我们使用golang的gin框架进行web server的开发,对于传来的json参数进行校验,这个是必不可少的,只要是传过来的参数,就不可信。
validate的tag校验类型见官方文档-参考。
话不多说,直接上代码示例:
package main
import (
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"net/http"
)
type User struct {
Username string `json:"username" validate:"required,min=4,max=20"` // 必填字段,限制长度
Password string `json:"password" validate:"required"` // 必填字段
Email string `json:"email" validate:"required,email"` // 限于email格式
Phone string `json:"phone" validate:"omitempty,numeric"` // 限于数字型
Hobby []string `json:"hobby" validate:"omitempty"` // 空时忽略
Age int `json:"age" validate:"omitempty,gt=18,lt=100"` // 限制大小
Gender string `json:"gender" validate:"omitempty,oneof=male female"` // 限于男女
}
func main() {
router := gin.Default()
router.POST("/login", login)
_ = router.Run(":8080")
}
func login(ctx *gin.Context) {
var user User
err := ctx.ShouldBindJSON(&user)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()})
return
}
// repeat parse use below
//_ = ctx.ShouldBindWith(&user, binding.JSON)
validate := validator.New()
err = validate.Struct(user)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()})
return
}
ctx.JSON(http.StatusOK, gin.H{"msg": "success"})
}
启动server,postman测试,可以看到哪些字段因为某个校验不能通过校验,导致error, 是不是很友好呢,不过建议返回前台校验参数失败即可,具体校验详情作为日志输出到server的log文件中。
3.进阶示例-自定义字段或验证方法
3.1 自定义规则
代码源自: http://liuqh.icu/2021/05/30/go/gin/11-validate/
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
)
// 验证pre
type CustomParam struct {
Pre string `validate:"pre=go_"`
}
func main() {
// 实例化验证器
validate = validator.New()
// 注册自定义标签
_ = validate.RegisterValidation("pre", ValidatePre)
cusParam := CustomParam{
Pre: "php_",
}
err := validate.Struct(cusParam)
fmt.Println(err)
}
// 自定义验证规则
func ValidatePre(fl validator.FieldLevel) bool {
return fl.Field().String() == "go_"
}
3.2 自定义规则在gin中使用
代码源自: http://liuqh.icu/2021/05/30/go/gin/11-validate/
有自定义的validator,tag的类型设为binding。
package main
import (
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-playground/validator/v10"
"net/http"
"time"
)
// 定义结构体
type User struct {
Name string `form:"name" binding:"required,min=3,max=5" `
BirthDate time.Time `form:"date" binding:"required,birth" time_format:"2006-01-02"`
}
// 运行程序
func main() {
engine := gin.Default()
// 注册自定义验证标签:birth
if validate,ok := binding.Validator.Engine().(*validator.Validate);ok {
validate.RegisterValidation("birth",checkBirthDate)
}
// 接收请求
engine.GET("/valid", func(context *gin.Context) {
var user User
// 集成验证
err := context.ShouldBindQuery(&user)
if err != nil {
context.JSON(http.StatusBadRequest,gin.H{"error":err.Error()})
return
}
context.JSON(http.StatusOK,gin.H{"msg":"success"})
})
_ = engine.Run()
}
// 检测生日
func checkBirthDate(fl validator.FieldLevel) bool {
t,ok := fl.Field().Interface().(time.Time)
if ok {
// 当前时间应该大于生日时间
if time.Now().After(t) {
return true
}
}
return false
}
4.binding && validator
见参考文档:Gin请求参数校验
参考文档