11

gin请求数据校验

 4 years ago
source link: https://studygolang.com/articles/28300
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

前言

最近优化 gin+vue的前后端分离项目 代码时候,发现代码中对请求数据的校验比较繁琐,于是想办法简化它。最终我发现了 go-playground/validator 开源库很好用。

优化前代码

代码如下:

UZbA3me.png!web

发现每个方法都这样校验数据,很繁琐。

优化代码

这里使用 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的数据请求校验了,接下来看下优化后的代码。

优化后代码

iyYbQjA.png!web

只需要正常使用 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://github.com/Bingjian-Zhu/gin-vue-admin


Recommend

  • 82
    • zhuanlan.zhihu.com 6 years ago
    • Cache

    ThinkJS中数据解析和校验

  • 96
    • www.10tiao.com 6 years ago
    • Cache

    ThinkJS 中数据解析和校验

    编者按:本文转载自 ThinkJS 知乎专栏。 Web 服务的整个流程中,获取数据是最重要的一环,如何方便快捷的获取用户提交的数据减少开发者的开发成本是一个 Web 服务框架应该考虑的事情。本文将会为大家介绍在 ThinkJS 中请求数据解...

  • 39
    • 掘金 juejin.im 6 years ago
    • Cache

    前端数据校验从建模开始

    前端开发过程中你们觉得处理什么业务功能最烦人? 做前端已经有很长一段时间了,不知道大家是否和我有同样的感受,在一些 Web 应用中表单处理起来比其他功能模块都麻烦,很多体力活,往往在数据的校验会很费时间。 为了能够把这部分代码更有条理,我们把数据校验部...

  • 23
    • studygolang.com 4 years ago
    • Cache

    gin - validator 参数校验

    最近自己也在用gin框架做项目,然后在群里也有人问关于,参数验证的问题,今天有时间正好研究一下。 gin版本 : v1.6.2 基本验证 定义参数绑定结构体 account_io.go pack...

  • 27
    • 微信 mp.weixin.qq.com 4 years ago
    • Cache

    数据一致性校验及数据同步,运维必看

    主从数据不一致对DBA来说是一个比较头疼的事情,刚接触MySQL时,遇到这种问题我一般采用重新还原备库的方式恢复数据,这对我来说是个很痛苦的过程。今天就来介绍两款pt工具,通过这两款工具可以针对数据不一致的情况进行快速检测...

  • 2
    • segmentfault.com 3 years ago
    • Cache

    使用TypeScript校验运行时数据

    对于前端程序猿,常见的开发流程是:前后端约定接口后端给出接口文档根据接口编写 TypeScript 类型定义开发完成进行联调虽然一切顺利,但是上线后还是翻车了,js 报错:cannot read the property 'x...

  • 2
    • www.xiabingbao.com 3 years ago
    • Cache

    nodejs 中如何校验请求中的 referer

    nodejs 中如何校验请求中的 referer 蚊子前端博客 发布于 2021-11-22 23:51 使用nodejs做服务器,接收到的请求千奇百怪,如何判断请求中的referer呢? 我们在写...

  • 2
    • wnanbei.github.io 2 years ago
    • Cache

    Gin 请求与路由

    Go第三方库

  • 14
    • wnanbei.github.io 2 years ago
    • Cache

    Gin 获取请求数据

    Go第三方库

  • 6

    Spring Boot下如何校验Spring MVC的请求参数及如何自定义校验注解 作者:爱科学的卫斯理 2022-11-10 07:53:54 Spring Boot提供了spring-boot-starter-validation 为Bean的校验提供支持。我们可以通过一系列的校验...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK