前言

最近优化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. Nginx 实现API 网关

    1,网关 网关(Gateway)就是一个网络连接到另一个网络的“关口”. 在Nginx 配置负载均衡之后,可以进入到网关,在网关决定进入到哪个真实的web 服务器. 2,将Ngnix 配置 API 网 ...

  2. SpringBoot常见注解的解释

    @Component 这个注解类似SSM中的Controller和Service注解 ,将加了这个注解的类装配到Sping容器内,这样就可以在其他类用@Autowired注解实现依赖注入. @Conf ...

  3. 字符串学习笔记(二)---- StringBuffer

    一.相关介绍 1.StringBuffer介绍 StringBuffer对象是字符串缓冲区对象,用于存放数据的容器 2.StringBuffer特点 StringBuffer(字符串缓冲区对象)的长度 ...

  4. 深入解读ES6系列(四)

    来自老曾es6的前言: 哈喽小伙伴们,爱说'废'话的Z又回来了,欢迎来到Super IT曾的博客时间,上一节说了字符串,面向对象以及json的知识,这一节我们继续我们知识的海洋,一起奋斗不秃头!不足的 ...

  5. .NET Core项目部署到Linux(Centos7)(九)防火墙配置,允许外网或局域网访问.NET Core站点

    目录 1.前言 2.环境和软件的准备 3.创建.NET Core API项目 4.VMware Workstation虚拟机及Centos 7安装 5.Centos 7安装.NET Core环境 6. ...

  6. DevEco Toolkit使用指南--平行视界

      高效开发和创新业务是开发者一直追求的目标,当接到开发需求时,如果可以找到现成的API调用,能为开发者节省大把时间,将会留有更多的时间进行业务的创新.华为DevEcoToolkit聚合了华为丰富的开 ...

  7. MySQL学习之路6-数据表连接方式

    内连接 关键字: inner join  on 语句:select * from <a_table> inner join <b_table> on a.id = b.id ; ...

  8. jsonpath 字典中取值

    jsonpath 第三方模块 def getsign(): url="http://api.nnzhp.cn/api/user/login" data = {"usern ...

  9. k8s yaml示例

    Kind选择 https://kubernetes.io/zh/docs/concepts/workloads/controllers/ Pod示例 apiVersion : v1 #版本v1 kin ...

  10. 从零搭建一个SpringCloud项目之Config(五)

    配置中心 一.配置中心服务端 新建项目study-config-server 引入依赖 <dependency> <groupId>org.springframework.cl ...