gin请求数据校验
前言#
最近优化gin+vue的前后端分离项目代码时候,发现代码中对请求数据的校验比较繁琐,于是想办法简化它。最终我发现了go-playground/validator开源库很好用。
优化前代码#
代码如下:
发现每个方法都这样校验数据,很繁琐。
优化代码#
这里使用go-playground/validator开源库来简化请求校验。
1.安装go-playground/validator
# 使用 Go Modules
go env -w GO111MODULE=on
# 安装 go-playground/validator
go get github.com/go-playground/validator/v10
注意:v10版本是使用Go Modules,运行
go get github.com/go-playground/validator/v10
前需要确保GO111MODULE=on
,不然会报:cannot find package "github.com/go-playground/validator/v10"
2.实现StructValidator
接口的两个方法
StructValidator
是需要实现的最基本的接口,作为验证引擎来确保请求的正确性。
type StructValidator interface {
ValidateStruct(interface{}) error
Engine() interface{}
}
ValidateStruct
:如果接收到的类型是一个结构体或指向结构体的指针,则执行验证。Engine
: 返回支持StructValidator
实现的底层验证引擎。
实现接口:
package validator
import (
"reflect"
"sync"
"github.com/gin-gonic/gin/binding"
"github.com/go-playground/validator/v10"
)
type DefaultValidator struct {
once sync.Once
validate *validator.Validate
}
var _ binding.StructValidator = &DefaultValidator{}
// ValidateStruct 如果接收到的类型是一个结构体或指向结构体的指针,则执行验证。
func (v *DefaultValidator) ValidateStruct(obj interface{}) error {
if kindOfData(obj) == reflect.Struct {
v.lazyinit()
//如果传递不合规则的值,则返回InvalidValidationError,否则返回nil。
///如果返回err != nil,可通过err.(validator.ValidationErrors)来访问错误数组。
if err := v.validate.Struct(obj); err != nil {
return err
}
}
return nil
}
// Engine 返回支持`StructValidator`实现的底层验证引擎
func (v *DefaultValidator) Engine() interface{} {
v.lazyinit()
return v.validate
}
func (v *DefaultValidator) lazyinit() {
v.once.Do(func() {
v.validate = validator.New()
v.validate.SetTagName("validate")
// //v8版本,v8版本使用"binding"
// v.validate.SetTagName("binding")
})
}
func kindOfData(data interface{}) reflect.Kind {
value := reflect.ValueOf(data)
valueType := value.Kind()
if valueType == reflect.Ptr {
valueType = value.Elem().Kind()
}
return valueType
}
3.使用该验证引擎
修改model
,添加validate
验证
type Article struct {
ID int `gorm:"primary_key" json:"id"`
State int `json:"state" validate:"min=0,max=1"`
TagID int `json:"tag_id" validate:"gt=0"`
Title string `json:"title" validate:"required"`
Desc string `json:"desc" validate:"required"`
Content string `json:"content" validate:"required"`
CoverImageURL string `json:"cover_image_url"`
CreatedBy string `json:"created_by" validate:"required"`
ModifiedBy string `json:"modified_by"`
}
最后,只需在main
函数中添加这行代码:
package main
import (
"github.com/gin-gonic/gin/binding"
"github.com/bingjian-zhu/gin-vue-admin/common/validator"
)
func main() {
binding.Validator = new(validator.DefaultValidator)
// regular gin logic
}
以上,我们就完成了gin的数据请求校验了,接下来看下优化后的代码。
优化后代码#
只需要正常使用c.Bing(model)
就可以对请求的数据进行校验了,代码简化了许多。
常用校验规则介绍#
type Test struct {
ID int `validate:"required"` //数字确保不为0
Name string `validate:"required,min=1,max=8"` //字符串确保不为"",且长度 >=1 && <=8 (min=1,max=8等于gt=0,lt=9)
Value string `validate:"required,gte=1,lte=8"` //字符串确保不为"",且长度 >=1 && <=8
Status int `validate:"min=1,max=10"` //最小为0,最大为10(min=0,max=10等于gt=0,lt=11)
PhoneNumber string `validate:"required,len=11"` //不为""且长度为11
Time string `validate:"datetime=2006-01-02"` //必须如2006-01-02的datetime格式
Color string `validate:"oneof=red green"` //是能是red或者green
Size int `validate:"oneof=37 39 41"` //是能是37或者39或者41
Email string `validate:"email"` //必须邮件格式
JSON string `validate:"json"` //必须json格式
URL string `validate:"url"` //必须url格式
UUID string `validate:"uuid"` //必须uuid格式
}
更多校验规则可以阅读源码文档。
总结#
go-playground/validator开源库把gin的请求校验简单化了,使得我们代码更简单易读。
以上只是对结构体做请求校验,对于非结构体的请求校验,用老办法
import "github.com/astaxie/beego/validation"
func (a *Article) GetArticle(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
valid := validation.Validation{}
valid.Min(id, 1, "id").Message("ID必须大于0")
var data *models.Article
code := codes.InvalidParams
if !valid.HasErrors() {
data = a.Service.GetArticle(id)
code = codes.SUCCESS
} else {
for _, err := range valid.Errors {
a.Log.Info("err.key: %s, err.message: %s", err.Key, err.Message)
}
}
RespData(c, http.StatusOK, code, data)
}
作者: 烟花易冷人憔悴
出处:https://www.cnblogs.com/FireworksEasyCool/p/12794311.html
版权:本文采用「署名-非商业性使用-相同方式共享 4.0 国际」知识共享许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?