go gin web 应用 实现 参数校验 自定义功能
1.准备工作
在进行 web
业务开发时,尽管 validator/v10
这个库已经为我们预置了很多校验的字段约束,难免有些场景下,我们想自定义一些规则进去,比如校验用户注册的密码,约束是含数字、大写字母、小写字母,特殊字符("*|&|$|#")的至少3种,常规的字段约束此时就不管用了,怎么办,当然可以通过自定义约束字段检验,自己操作的空间就大很多了。
根据 validator
库的相关规则,只要我们实现了如下函数:
// Func accepts a FieldLevel interface for all validation needs. The return // value should be true when validation succeeds. type Func func(fl FieldLevel) bool
就可以根据在定义 struct
时的 tag
字段注册到 validator
中。
怎样是不是很简单,接下来我们以简单的用户注册与用户登录的场景来实操下。
2.相关代码
目录结构
业务代码
项目启动
// main.go package main import ( "github.com/gin-gonic/gin" v1 "go-gin-userDefinedValidator/api/v1" ) func main() { r := gin.Default() r.GET("/hello", v1.Hello) r.POST("/user/add", v1.AddUser) r.POST("/auth/login", v1.Login) _ = r.Run(":8080") }
接口路由函数
// router.go package v1 import ( "fmt" "net/http" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "github.com/go-playground/validator/v10" "go-gin-userDefinedValidator/internal/request" validate "go-gin-userDefinedValidator/internal/validator" ) func Hello(ctx *gin.Context) { ctx.JSON(http.StatusOK, gin.H{ "msg": "hello, this is from gin app server.", }) } func AddUser(ctx *gin.Context) { var err error var user request.UserParams err = ctx.ShouldBindBodyWith(&user, binding.JSON) if err != nil { ctx.JSON(http.StatusOK, gin.H{ "msg": err.Error(), }) return } err = validate.Validate.Struct(user) if err != nil { details := make([]map[string]interface{}, 0) for _, e := range err.(validator.ValidationErrors) { m := make(map[string]interface{}) m["field"] = e.Field() m["value"] = e.Value() m["tag"] = e.Tag() details = append(details, m) } ctx.JSON(http.StatusOK, gin.H{ "msg": "validate error", "details": details, }) return } ctx.JSON(http.StatusOK, gin.H{ "msg": fmt.Sprintf("Registered success, welcome user: %s", user.Username), }) } func Login(ctx *gin.Context) { var err error var login request.LoginParams err = ctx.ShouldBindBodyWith(&login, binding.JSON) if err != nil { ctx.JSON(http.StatusOK, gin.H{ "msg": err.Error(), }) return } err = validate.Validate.Struct(login) if err != nil { details := make([]map[string]interface{}, 0) for _, e := range err.(validator.ValidationErrors) { m := make(map[string]interface{}) m["field"] = e.Field() m["value"] = e.Value() m["tag"] = e.Tag() details = append(details, m) } ctx.JSON(http.StatusOK, gin.H{ "msg": "validate error", "details": details, }) return } ctx.JSON(http.StatusOK, gin.H{ "msg": fmt.Sprintf("user: %s, login success.", login.Username), }) }
接口请求参数
// reqParams.go package request type UserParams struct { Username string `json:"username" validate:"required,min=4,max=20"` Password string `json:"password" validate:"required,passwd"` ConfirmPassword string `json:"confirmPassword" validate:"required,eqfield=Password"` Age int `json:"age,omitempty" validate:"omitempty,age"` Gender int `json:"gender,omitempty" validate:"omitempty,oneof=1 0"` } type LoginParams struct { Username string `json:"username" validate:"required,min=4,max=20"` Password string `json:"password" validate:"required,passwd"` }
自定义验证器
// myValidator.go package validator import ( "fmt" "github.com/go-playground/validator/v10" ) var Validate *validator.Validate // 初始化注册自定义校验 func init() { registerMyValidator() } func registerMyValidator() { Validate = validator.New() err := Validate.RegisterValidation("passwd", passwdFunc) if err != nil { fmt.Println("register passwd validator failed.") return } err = Validate.RegisterValidation("age", ageFunc) if err != nil { fmt.Println("register age validator failed.") return } fmt.Println("register user defined validator success.") } // user defined validator // 定义密码验证 func passwdFunc(fl validator.FieldLevel) bool { pwd := fl.Field().String() if len(pwd) < 8 || len(pwd) > 20 { return false } return true } // 定义age验证 func ageFunc(fl validator.FieldLevel) bool { age := fl.Field().Int() if age < 18 || age > 100 { return false } return true }
示例中,我们以简单的密码和年龄校验为例,实现了简单业务,下面看看相关测试。
3.测试
hello 接口
正常注册请求参数
多个字段参数问题
正常登陆
异常登陆
通过本示例的学习,相信你也可以轻松掌握自定义验证器的使用。
参考文章:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2021-03-25 django项目实战-基本指南
2021-03-25 django项目使用mysql作为数据库配置
2021-03-25 python logging模块的快速应用-输出到文件
2021-03-25 linux 安装mysql及常用配置 授权 改密 开放端口