Gin对请求参数自定义验证规则可以分三步:

  • 自定义结构体验证绑定binding标签
  • 针对该标签定义验证方法
  • 再将该验证方法注册到validator验证器里面

自定义结构体验证绑定binding标签

需要在请求参数结构体后面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"`

 针对该标签定义验证方法

方法名自定义,同时需要引入"gopkg.in/go-playground/validator.v8"这个包,传入参数于下面例子里保持一致即可,通过断言从field字段拿到需要验证参数,再通过相应逻辑判断返回true和false,实现参数验证

//定义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 today.Year() > date.Year() || today.YearDay() > date.YearDay() {
			return false
	return true

 将该验证方法注册到validator验证器里面

将该验证方法注册到validator验证器里面,要注意标签与验证方法的对应,具体使用方法如下面代码:

 //将验证方法注册到验证器中
	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
		v.RegisterValidation("bookabledate", bookableDate)

 完整例子如下

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()})

测试结果:

devops$ curl -X GET http://localhost:8080/bookable?check_in=2019-09-20&check_out=2019-09-21
{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'required' tag"}
devops$ curl -X GET http://localhost:8080/bookable?check_in=2019-11-20&check_out=2019-11-21
{"message": "Booking dates are valid!"}

如有问题,欢迎指正,相互学习,共同进步。

Gin对请求参数自定义验证规则可以分三步:自定义结构体验证绑定binding标签 针对该标签定义验证方法 再将该验证方法注册到validator验证器里面自定义结构体验证绑定binding标签需要在请求参数结构体后面binding,加入自定义验证标签,如bookabledate标签,用于验证预约时间必须大于今天type Booking struct { CheckIn ti... 测试用户名:admin 测试密码:123456 Gin-vue-admin是一个基于vue和gin开发的全栈前后端分离的后台管理系统,集成jwt鉴权,动态路由,动态菜单,casbin鉴权,表单生成器,代码生成器等功能,提供多种示例文件,让您把更多时间专注在业务开发上。 1.2 贡献指南 Hi! 首先感谢你使用 gin-vue-admin。 Gin-vue-admin 是一套为后台管理平台准备的一整套前后端分离架构式的开源框架,旨在快速搭建后台管理系统。 Gin-vue-admin 的成长离不开大家的支持,如果你愿意为 gin-vue-admin 贡献代码或提供建议,请阅读以下内容。 1.2.1 Issue 规范 issue 仅用于 感谢开源项目gin-vue-admin,以及1010工作室的教程,项目文档 我只是在跟着学习,然后记录下笔记而已,可能会有新的代码加入,但是本质还是跟着学习的一个过程。 所谓的绑定就是先建立一个结构体,然后将接收到的参数通过绑定的形式直接映射上去 bind模式以及如何使用 在使用绑定模式时有两种方式,即must bind和should bind。 must bind Methods: Bind, BindJSON, BindXML, BindQuery, BindYAML Behavior 这次方法
Go 使用validator进行后端数据校验一、概述二、操作符说明三、常用标记说明四、标记使用注意五、使用示例 包下载:go get github.com/go-playground/validator/v10 在接口开发经常会遇到一个问题是后端需要写大量的繁琐代码进行数据校验,所以就想着有没有像前端校验一样写规则进行匹配校验,然后就发现了validator包,一个比较强大的校验工具包下面是一些学习总结,详细内容可以查看[validator](https://github.com/go-play
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "github.com/go-playground/validator/v10" // Booking 包含绑定和验证的数据。 type Booking struc 首先定义一个接受数据用的DTO结构体,叫做LoginDTO type LoginDto struct { Username string `json:"username" binding:"required" msg:"用户名不能为空"` Password string `json:"password"
gin 框架如何获取全部请求参数? 当明确接口的时候我们可以定义一个结构体去绑定参数到定义好的结构体中。 如果是在中间件中要获取全部参数另做他用,比如验签等操作,动态去获取全部参数时如何做呢? gin框架只提供了根据key获取参数的方法,所以我们需要自己定义方法去获取全部参数,下面以gin框架获取get请求中所有参数为例把全部query参数获取并绑定到一个`map[string]any`(go 1.18版本前为 `map[string]interface{}` 写法)中。...
在 Go Gin 框架中,如果想让路径参数可以为空,可以在路由定义中使用通配符 `:param` 和问号 `?` 来实现。 例如,如果要让路径参数 `userID` 可以为空,可以这样定义路由: r.GET("/users/:userID?", handleUser) 在处理函数 `handleUser` 中,就可以通过 Gin 的上下文对象 `c` 获取路径参数的值: func handleUser(c *gin.Context) { userID := c.Param("userID") // 如果 userID 为空,可以在此处进行相应的处理 注意,在使用问号标记路径参数可空时,如果实际请求中没有传递该参数,则获取到的参数值为空字符串。如果想要在路径参数没有传递的情况下区分是否真的为空,可以使用 Gin 提供的 `c.DefaultQuery` 函数获取路径参数的默认值。 例如,在处理函数中可以这样获取路径参数 `userID` 的值: userID := c.DefaultQuery("userID", "") if userID == "" { // 表示路径参数 userID 没有传递 这样就可以在路径参数为空或者没有传递的情况下进行相应的处理了。
now = time.Now() next = now.Add(time.Hour * 24) next = time.Date(next.Year(), next.Month(), next.Day(), 0, 0, 0, 0, next.Location()) t = time.NewTimer(next.Sub(now)) [/code]