时间:2021-05-22
golang常用库:gorilla/mux-http路由库使用
golang常用库:配置文件解析库-viper使用
golang常用库:操作数据库的orm框架-gorm基本使用
golang常用库:字段参数验证库-validator使用
一、背景
在平常开发中,特别是在web应用开发中,为了验证输入字段的合法性,都会做一些验证操作。比如对用户提交的表单字段进行验证,或者对请求的API接口字段进行验证,验证字段的合法性,保证输入字段值的安全,防止用户的恶意请求。
一般的做法是用正则表达式,一个字段一个字段的进行验证。一个一个字段验证的话,写起来比较繁琐。那有没更好的方法,进行字段的合法性验证?有, 这就是下面要介绍的 validator 这个验证组件。
代码地址:
https://github.com/go-playground/validator
文档地址:
https://github.com/go-playground/validator/blob/master/README.md
二、功能介绍
这个验证包 github.com/go-playground/validator 验证功能非常多。
标记之间特殊符号说明
范围比较验证
doc: https://github.com/go-playground/validator/blob/master/README.md#comparisons
范围验证: 切片、数组和map、字符串,验证其长度;数值,验证大小范围
例子:
type User struct { Name string `json:"name" validate:"min=0,max=35"` Age unit8 `json:"age" validate:"lte=0,gte=90"`}更多功能请参看文档 validator comparisons doc
字符串验证
doc: https://github.com/go-playground/validator/blob/master/README.md#strings
例子:
type User struct { Name string `validate:"contains=tom"` Age int `validate:"min=1"`}更多功能请参看文档 validator strings doc
字段验证
doc: https://github.com/go-playground/validator/blob/master/README.md#fields
eqcsfield:跨不同结构体字段验证,比如说 Struct1 Filed1,与结构体Struct2 Field2相等,
type Struct1 struct { Field1 string `validate:eqcsfield=Struct2.Field2` Struct2 struct { Field2 string }}nefield:同一结构体字段验证不相等
type User struct { Name string `validate:"lte=4"` Age int `validate:"min=20"` Password string `validate:"min=10,nefield=Name"`}更多功能请参看文档:validator Fields DOC
网络验证
doc: https://github.com/go-playground/validator/blob/master/README.md#network
更多功能请参看文档:validator network DOC
Format
doc: https://github.com/go-playground/validator/blob/master/README.md#format
base64:字段值是否包含有效的base64值
更多功能请参看文档 validator strings doc
其他
请参看文档: https://github.com/go-playground/validator/blob/master/README.md#other
三、安装
go get:
go get github.com/go-playground/validator/v10
在文件中引用validator包:
import "github.com/go-playground/validator/v10"
四、validator使用
文档:https://github.com/go-playground/validator/blob/master/README.md#examples
例子1:验证单个字段变量值
validation1.go
package mainimport ( "fmt" "github.com/go-playground/validator/v10")func main() { validate := validator.New() var boolTest bool err := validate.Var(boolTest, "required") if err != nil { fmt.Println(err) } var stringTest string = "" err = validate.Var(stringTest, "required") if err != nil { fmt.Println(err) } var emailTest string = "test@126.com" err = validate.Var(emailTest, "email") if err != nil { fmt.Println(err) } else { fmt.Println("success") // 输出: success。 说明验证成功 } emailTest2 := "test.126.com" errs := validate.Var(emailTest2, "required,email") if errs != nil { fmt.Println(errs) // 输出: Key: "" Error:Field validation for "" failed on the "email" tag。验证失败 } fmt.Println("\r\nEnd!!") }运行输出:
go run simple1.go
Key: '' Error:Field validation for '' failed on the 'required' tag
Key: '' Error:Field validation for '' failed on the 'required' tag
success
Key: '' Error:Field validation for '' failed on the 'email' tag
End!!
例子2:验证结构体struct
from:struct validate
validation_struct.go,这个程序还列出了效验出错字段的一些信息,
package mainimport ( "fmt" "github.com/go-playground/validator/v10")type User struct { FirstName string `validate:"required"` LastName string `validate:"required"` Age uint8 `validate:"gte=0,lte=130"` Email string `validate:"required,email"` Addresses []*Address `validate:"required,dive,required"`}type Address struct { Street string `validate:"required"` City string `validate:"required"` Planet string `validate:"required"` Phone string `validate:"required"`}func main() { address := &Address{ Street: "Eavesdown Docks", Planet: "Persphone", Phone: "none", } user := &User{ FirstName: "Badger", LastName: "Smith", Age: 135, Email: "Badger.Smith@gmail.com", Addresses: []*Address{address}, } validate := validator.New() err := validate.Struct(user) if err != nil { fmt.Println("=== error msg ====") fmt.Println(err) if _, ok := err.(*validator.InvalidValidationError); ok { fmt.Println(err) return } fmt.Println("\r\n=========== error field info ====================") for _, err := range err.(validator.ValidationErrors) { // 列出效验出错字段的信息 fmt.Println("Namespace: ", err.Namespace()) fmt.Println("Fild: ", err.Field()) fmt.Println("StructNamespace: ", err.StructNamespace()) fmt.Println("StructField: ", err.StructField()) fmt.Println("Tag: ", err.Tag()) fmt.Println("ActualTag: ", err.ActualTag()) fmt.Println("Kind: ", err.Kind()) fmt.Println("Type: ", err.Type()) fmt.Println("Value: ", err.Value()) fmt.Println("Param: ", err.Param()) fmt.Println() } // from here you can create your own error messages in whatever language you wish return }}运行 输出:
$ go run validation_struct.go
=== error msg ====
Key: 'User.Age' Error:Field validation for 'Age' failed on the 'lte' tag
Key: 'User.Addresses[0].City' Error:Field validation for 'City' failed on the 'required' tag
=========== error field info ====================
Namespace: User.Age
Fild: Age
StructNamespace: User.Age
StructField: Age
Tag: lte
ActualTag: lte
Kind: uint8
Type: uint8
Value: 135
Param: 130
Namespace: User.Addresses[0].City
Fild: City
StructNamespace: User.Addresses[0].City
StructField: City
Tag: required
ActualTag: required
Kind: string
Type: string
Value:
Param:
还可以给字段加一些其他tag信息,方面form,json的解析,如下:
type User struct { FirstName string `form:"firstname" json:"firstname" validate:"required"` LastName string `form:"lastname" json:"lastname" validate:"required"` Age uint8 ` form:"age" json:"age"validate:"gte=0,lte=130"` Email string ` form:"email" json:"email" validate:"required,email"`}用户自定义函数验证
用户自定义函数验证字段是否合法,效验是否正确。
例子3: 通过字段tag自定义函数
validate.RegisterValidation
customer_tag.go:
package mainimport ( "fmt" "github.com/go-playground/validator/v10")type User struct { Name string `form:"name" json:"name" validate:"required,CustomerValidation"` //注意:required和CustomerValidation之间不能有空格,否则panic。CustomerValidation:自定义tag-函数标签 Age uint8 ` form:"age" json:"age" validate:"gte=0,lte=80"` //注意:gte=0和lte=80之间不能有空格,否则panic}var validate *validator.Validatefunc main() { validate = validator.New() validate.RegisterValidation("CustomerValidation", CustomerValidationFunc) //注册自定义函数,前一个参数是struct里tag自定义,后一个参数是自定义的函数 user := &User{ Name: "jimmy", Age: 86, } fmt.Println("first value: ", user) err := validate.Struct(user) if err != nil { fmt.Printf("Err(s):\n%+v\n", err) } user.Name = "tom" user.Age = 29 fmt.Println("second value: ", user) err = validate.Struct(user) if err != nil { fmt.Printf("Err(s):\n%+v\n", err) }}// 自定义函数func CustomerValidationFunc(f1 validator.FieldLevel) bool { // f1 包含了字段相关信息 // f1.Field() 获取当前字段信息 // f1.Param() 获取tag对应的参数 // f1.FieldName() 获取字段名称 return f1.Field().String() == "jimmy"}运行输出:
$ go run customer.go
first value: &{jimmy 86}
Err(s):
Key: 'User.Age' Error:Field validation for 'Age' failed on the 'lte' tag
second value: &{tom 29}
Err(s):
Key: 'User.Name' Error:Field validation for 'Name' failed on the 'CustomerValidation' tag
**注意:
上面代码user struct定义中 ,validate里的required和CustomerValidation之间不能有空格,否则运行时报panic错误:panic: Undefined validation function ' CustomerValidation' on field 'Name'
例子4:自定义函数-直接注册函数1
不通过字段tag自定义函数,直接注册函数。
RegisterStructValidation
https://github.com/go-playground/validator/blob/master/_examples/struct-level/main.go
customer1.go
package mainimport ( "fmt" "github.com/go-playground/validator/v10")type User struct { FirstName string `json:firstname` LastName string `json:lastname` Age uint8 `validate:"gte=0,lte=130"` Email string `validate:"required,email"` FavouriteColor string `validate:"hexcolor|rgb|rgba"`}var validate *validator.Validatefunc main() { validate = validator.New() validate.RegisterStructValidation(UserStructLevelValidation, User{}) user := &User{ FirstName: "", LastName: "", Age: 30, Email: "TestFunc@126.com", FavouriteColor: "#000", } err := validate.Struct(user) if err != nil { fmt.Println(err) }}func UserStructLevelValidation(sl validator.StructLevel) { user := sl.Current().Interface().(User) if len(user.FirstName) == 0 && len(user.LastName) == 0 { sl.ReportError(user.FirstName, "FirstName", "firstname", "firstname", "") sl.ReportError(user.LastName, "LastName", "lastname", "lastname", "") }}运行输出:
$ go run customer1.go
Key: 'User.FirstName' Error:Field validation for 'FirstName' failed on the 'firstname' tag
Key: 'User.LastName' Error:Field validation for 'LastName' failed on the 'lastname' tag
例子5:自定义函数-直接注册函数2
RegisterCustomTypeFunc
https://github.com/go-playground/validator/blob/master/_examples/custom/main.go
validate.RegisterCustomTypeFunc:验证类型的自定义函数
customer2.go:
package mainimport ( "database/sql" "database/sql/driver" "fmt" "reflect" "github.com/go-playground/validator/v10")type DbBackedUser struct { Name sql.NullString `validate:"required"` Age sql.NullInt64 `validate:"required"`}var validate *validator.Validatefunc main() { validate = validator.New() validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{}) // build object for validation x := DbBackedUser{Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: false}} err := validate.Struct(x) if err != nil { fmt.Printf("Err(s):\n%+v\n", err) }}func ValidateValuer(field reflect.Value) interface{} { if valuer, ok := field.Interface().(driver.Valuer); ok { val, err := valuer.Value() if err == nil { return val } // handle the error how you want } return nil}运行输出:
$ go run customer.go
Err(s):
Key: 'DbBackedUser.Name' Error:Field validation for 'Name' failed on the 'required' tag
Key: 'DbBackedUser.Age' Error:Field validation for 'Age' failed on the 'required' tag
注意,这个函数:
RegisterCustomTypeFunc,它上面有2行注释:
// RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types
//
// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
它是一个验证数据类型自定义函数,NOTE:这个方法不是线程安全的
五、参考
https://github.com/go-playground/validator/blob/master/README.mdhttps://github.com/go-playground/validator/tree/master/_examples
总结
到此这篇关于golang常用库:字段参数验证库-validator使用的文章就介绍到这了,更多相关golang字段参数验证库validator内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
golang常用库:gorilla/mux-http路由库使用golang常用库:配置文件解析库-viper使用golang常用库:操作数据库的orm框架-go
golang常用库:gorilla/mux-http路由库使用golang常用库:配置文件解析库-viper使用golang常用库:操作数据库的orm框架-go
Hibernate识别数据库特有字段实例详解前言:Hibernate已经为绝大多数常用的数据库数据类型提供了内置支持,但对于某些数据库的专属字段支持就不够好了。
async-validator是一个异步验证的库,需要传入要验证的数据和验证规则官方链接https://github.com/yiminghe/async-va
GoLang提供了很多读文件的方式,一般来说常用的有三种。使用Read加上buffer,使用bufio库和ioutil库。那他们的效率如何呢?用一个简单的程序来