• [go每日一库] golang validator参数校验 Marathon


    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请求参数校验

    参考文档

  • 相关阅读:
    静态变量、静态方法说明
    DataGridView导出成excel实例
    异步执行小例子
    多线程操作的例子
    xmlReader遍历xml文档案例
    C#自动登录网页浏览页面 抓取数据
    datatable序列化成xml,xml反序列化成datatable
    TreeView递归法动态添加节点
    今天写的一个导出html页面的过程
    利用委托的BeginInvoke防止界面假死的实例
  • 原文地址:https://www.cnblogs.com/davis12/p/16404260.html
Copyright © 2020-2023  润新知