gin框架中的参数验证
结构体验证
用gin框架的数据验证,可以不用解析数据,减少if else,会简洁许多。
- 处理请求方法
func structValidator(context *gin.Context) {
var person Person
if err := context.ShouldBind(&person); err != nil {
fmt.Println(err)
context.String(http.StatusBadRequest, "failed")
return
}
context.JSON(http.StatusOK, &person)
}
- 验证结构体
type Person struct {
// 不能为空并且大于10
Age int `json:"age" form:"age" binding:"required,gt=10"`
Name string `json:"name" form:"name" binding:"required"`
Birthday time.Time `json:"birthday" form:"birthday" time_format:"2006-01-02 15:04:05" time_utc:"0"`
}
自定义验证 V10版本
依赖:github.com/go-playground/validator/v10
type Person struct {
// 不能为空并且大于10
Age int `json:"age" form:"age" binding:"required,gt=10"`
// 2、在参数 binding 上使用自定义的校验方法函数注册时候的名称
Name string `json:"name" form:"name" binding:"NotNullAndAdmin"`
Birthday time.Time `json:"birthday" form:"birthday" time_format:"2006-01-02"`
}
func NotNullAndAdmin(fl validator.FieldLevel) bool {
if value, ok := fl.Field().Interface().(string); ok {
// 字段不能为空,并且不等于 admin
return value != "" && !("admin" == value)
}
return false
}
func RegisterValidator() {
// 将我们自定义的校验方法注册到validator中
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
// 这里的 key 和 fn 可以不一样最终在 struct 使用的是 key
v.RegisterValidation("NotNullAndAdmin", NotNullAndAdmin)
}
}
func main() {
// 注册验证器
blog.RegisterValidator()
}
自定义验证器 V8版本
点击查看代码
package main
import (
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"gopkg.in/go-playground/validator.v8"
"net/http"
"reflect"
"time"
)
//binding 绑定一些验证请求参数,自定义标签bookabledate表示可预约的时期
type Booking struct {
CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckOut,bookabledate" time_format:"2006-01-02"`
}
//定义bookabledate标签对应的验证方法
func bookableDate(
v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
) bool {
if date, ok := field.Interface().(time.Time); ok {
today := time.Now()
if date.Unix() > today.Unix() {
return true
}
}
return false
}
func main() {
route := gin.Default()
//将验证方法注册到验证器中
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
v.RegisterValidation("bookabledate", bookableDate)
}
route.GET("/bookable", getBookable)
route.Run(":8080")
}
func getBookable(c *gin.Context) {
var b Booking
if err := c.ShouldBindWith(&b, binding.Query); err == nil {
c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
}
V10 版本示例2
func RegisterValidator() {
// 将我们自定义的校验方法注册到validator中
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
// 这里的 key 和 fn 可以不一样最终在 struct 使用的是 key
v.RegisterValidation("NotNullAndAdmin", NotNullAndAdmin)
v.RegisterValidation("bookableDate", bookableDate)
}
}
type Booking struct {
// 定义一个预约的时间大于今天的时间
CheckIn time.Time `json:"check_in" binding:"required,bookableDate" time_format:"2006-01-02"`
// gtfield=CheckIn退出的时间大于预约的时间
CheckOut time.Time `json:"check_out" binding:"required,gtfield=CheckIn" time_format:"2006-01-02"`
}
func bookableDate(fl validator.FieldLevel) bool {
if v, ok := fl.Field().Interface().(time.Time); ok {
currentTime := time.Now().Unix()
if currentTime > v.Unix() {
return false
}
}
return true
}
请求参数:
{
"check_in": "2021-12-13T8:16:25Z", // UTC时区
"check_out": "2021-12-13T16:16:26+08:00" // 中国:东八时区
}
gin框架中的参数验证的更多相关文章
- gin框架中请求参数的绑定与多数据格式处理
package main import ( "fmt" "github.com/gin-gonic/gin" ) // gin框架提供给开发者表单实体绑定的功能 ...
- Gin框架中文文档
Gin 是一个 go 写的 web 框架,具有高性能的优点.官方地址:https://github.com/gin-gonic/gin 带目录请移步 http://xf.shuangdeyu.com/ ...
- 在gin框架中使用JWT
在gin框架中使用JWT JWT全称JSON Web Token是一种跨域认证解决方案,属于一个开放的标准,它规定了一种Token实现方式,目前多用于前后端分离项目和OAuth2.0业务场景下. 什么 ...
- gin框架中的路由
基本路由 gin框架中采用的路由库是基于httrouter做的 地址为:https://github.com/julienschmidt/httprouter httprouter路由库 点击查看代码 ...
- Java中的参数验证(非Spring版)
1. Java中的参数验证(非Spring版) 1.1. 前言 为什么我总遇到这种非正常问题,我们知道很多时候我们的参数校验都是放在controller层的传入参数进行校验,我们常用的校验方式就是引入 ...
- golang gin框架中实现一个简单的不是特别精确的秒级限流器
起因 看了两篇关于golang中限流器的帖子: Gin 开发实践:如何实现限流中间件 常用限流策略--漏桶与令牌桶介绍 我照着用,居然没效果-- 时间有限没有深究.这实在是一个很简单的功能,我的需求是 ...
- gin框架中请求路由组的使用
1. gin框架中可以使用路由组来实现对路由的分类 package main import "github.com/gin-gonic/gin" func main() { rou ...
- django drf框架中的user验证以及JWT拓展的介绍
登录注册是几乎所有网站都需要去做的接口,而说到登录,自然也就涉及到验证以及用户登录状态保存,最近用DRF在做的一个关于网上商城的项目中,引入了一个拓展DRF JWT,专门用于做验证和用户状态保存.这个 ...
- 【解决了一个小问题】gin框架中出现如下错误:"[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 500"
POST到数据到一条gin框架的接口后,客户端收到400错误,并且返回了业务中返回的"decode json fail". 关键代码是: func report(c *gin.Co ...
随机推荐
- TensorFlow.NET机器学习入门【3】采用神经网络实现非线性回归
上一篇文章我们介绍的线性模型的求解,但有很多模型是非线性的,比如: 这里表示有两个输入,一个输出. 现在我们已经不能采用y=ax+b的形式去定义一个函数了,我们只能知道输入变量的数量,但不知道某个变量 ...
- 使用xlsx实现Excel导入
需求 实现在系统里批量导入数据,通过上传一个excel文件,前端将文件处理为json数据发送给后端.(最好与后端定义好上传的文件模板,方便处理数据) 实现 使用xlsx: xlsx的github地址: ...
- 使用PostMan测试WebService接口教程
一.操作步骤 1.设置URL 2.设置请求模式:Post 3.设置Header:添加 Content-Type ,值为 text/xml;charset=utf-8 4.设置Body:勾选raw 5. ...
- 网络编程之UDP(2)linux查看socket默认缓冲区大小和最大值
默认值 命令: cat /proc/sys/net/core/rmem_default 结果: 最大值 命令: cat /proc/sys/net/core/rmem_max 结果:
- Windows串口之解决包含setupapi.h还提示找不到符号报错
关于 本文演示环境: win10 1909 + VS2017 1. 错误信息 明明已经添加了头文件setupapi.h 和 库 setupapi.lib, 却还是提示报错,报错信息: 1>C:\ ...
- 【LeetCode】141. Linked List Cycle 解题报告(Java & Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 保存已经走过的路径 日期 [LeetCode ...
- 【LeetCode】215. Kth Largest Element in an Array 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:移除最大值 方法二:排序 方法三:大顶堆 方 ...
- MySQL中视图的定义、原理--触发器
视图概述 视图是一个虚拟表,其内容由查询定义.同真实的表一样,视图包含一系列带有名称的列和行数据.但是,视图并不在数据库中以存储的数据值集形式存在.行和列数据来自由定义视图的查询所引用的表,并且在引用 ...
- Java高级程序设计笔记 • 【第3章 多线程(二)】
全部章节 >>>> 本章目录 3.1 同步代码块 3.1 线程安全 3.1.1 模拟银行取款 3.1.2 同步代码块的使用 3.1.3 实践练习 3.2 同步方法 3.2. ...
- MongoDB常用命令(2)
1.创建数据库 use testdb 2.创建集合 db.t_member.insert({name:"zhaomin",age:23}) 3.查询 db.t_member.fin ...