前言

最近优化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://github.com/Bingjian-Zhu/gin-vue-admin

gin请求数据校验的更多相关文章

  1. Django rest-framework框架-请求数据校验

    验证实例: class UserInfoSerializer(serializers.Serializer): title = serializer.CharField(error_messages= ...

  2. Golang使用validator进行数据校验及自定义翻译器

    Golang使用validator进行数据校验及自定义翻译器 包下载:go get github.com/go-playground/validator/v10 一.概述 在接口开发经常会遇到一个问题 ...

  3. Struts2数据校验

    Struts2数据校验 1.常见数据校验方法 表单数据的校验方式: 表单中的数据必须被效验以后才能够被使用,常用的效验方式分为两种: 前台校验:也称之为客户端效验,主要是通过JS编程的方式进行表单数据 ...

  4. Struts 2 数据校验要用到的类和两种校验方式以及一些校验问题的解决

    通过继承ActionSupport类来完成Action开发,ActionSupport类不仅对Action接口进行简单实现, 同时增加了验证.本地化等支持 .真实开发中自定义Action都需要继承该类 ...

  5. (转)struts2:数据校验,通过XWork校验框架实现(validation.xml)

    转载自:http://www.cnblogs.com/nayitian/p/3475661.html struts2:数据校验,通过XWork校验框架实现(validation.xml)   根据输入 ...

  6. SpringMVC框架下数据的增删改查,数据类型转换,数据格式化,数据校验,错误输入的消息回显

    在eclipse中javaEE环境下: 这儿并没有连接数据库,而是将数据存放在map集合中: 将各种架包导入lib下... web.xml文件配置为 <?xml version="1. ...

  7. SpringMVC 数据转换 & 数据格式化 & 数据校验

    数据绑定流程 1. Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象 ...

  8. struts2 数据校验

    通过struts2中延续自xwork框架的validation.xml配置方式进行数据校验,因struts2 下存在三种请求参数的注入方式,固按照不同注入方式对validation.xml的配置进行总 ...

  9. mysql数据校验之字符集问题

    场景:主库DB:utf8字符集备库DB:gbk字符集 需求:校验主备数据是否一致,并且修复 校验过程:设置主库连接为utf8,设置备库连接为gbk,分别进行查询,将返回的的结果集按记录逐字段比较. 显 ...

随机推荐

  1. [洛谷2671]求和<前缀和&模拟>

    题目链接:https://www.luogu.org/problemnew/show/P2671 这是noip2015普及组的第三题,谁说的普及组的题就一定水的不行,这道题就比较有意思的 这道题的暴力 ...

  2. Gin框架系列01:极速上手

    Gin是什么? Gin是Go语言编写的web框架,具备中间件.崩溃处理.JSON验证.内置渲染等多种功能. 准备工作 本系列演示所有代码都在Github中,感兴趣的同学可以自行查阅,欢迎大家一起完善. ...

  3. 项目伪模块化开发之:requirejs(AMD)开发

    附:伪模块开发,终将会被es6的模块开发取代.其只为过渡阶段使用 一.为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码 ...

  4. PTA | 1009说反话(20分)

    给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式: 测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串.字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有 ...

  5. Linux基础:Day05

    iptables ip 的 tables ip的表格: iptables只是netfilter的前端管理工具:netfilter是linux内核提供的数据流量管理模块: iptables/netfil ...

  6. 测试老司机都在用的表白神器你会吗?-Fiddler之AutoResponse线上调试

    一.Fiddler在线调试功能和表白神器介绍 ​ 在以往的工作中,线上有bug,就需要把文件弄到本地来改,但经常会碰见本地环境又和线上不一样,导致调试困难,闭着眼睛改好之后传到线上去看对不对,不对的话 ...

  7. Tcl编程第四天,流程控制语句

    1. if {} { } elseif {} { } else { } 注意: 1.关键字 if elseif else 和大括号之间应该留有间距的.如果紧紧挨着会报错. 2.表条件的判断括号为大括号 ...

  8. es分页条数限制

    "error": { "root_cause": [ { "type": "query_phase_execution_excep ...

  9. Python设计模式(2)-策略模式

    # 策略模式和简单工厂模式相比,少了使用switch case 做判断,然后去实例化相应的 # 对象,比简单工厂模式更灵活. 它们代码的区别就在于此处使用了抽象类代替工厂类 # coding=utf- ...

  10. RESTful API设计的点

    RESTful API 前言 一直在使用RESTful API,但是好像概念还是很模糊的,总结下使用到的点 设计的规范 协议 API与用户的通信协议,总是使用HTTPs协议. 域名 应该尽量将API部 ...