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 ...
随机推荐
- JENKINS中创建全局变量并在JOB中使用
配置了一个 "PASSWORD"的变量值 然后再脚本里面使用 注意这里必须要用双引号 不然不行
- C++之递归遍历数组
倒序输出 源码 void print_arr_desc(int arr[], unsigned int len) { if (len) { std::cout << "a[&qu ...
- 【LeetCode】123. Best Time to Buy and Sell Stock III 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- 【LeetCode】144. Binary Tree Preorder Traversal 解题报告(Python&C++&Java)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 迭代 日期 题目地址:https://leetc ...
- CSS实现鼠标移入时图片的放大效果以及缓慢过渡
transform:scale()可以实现按比例放大或者缩小功能. transition可以设置动画执行的时间,实现缓慢或者快速的执行动画,效果图如下: 源码: <!DOCTYPE html&g ...
- Chapter 12 IP Weighting and Marginal Structural Model
目录 12.1 The causal question 12.2 Estimating IP weights via modeling 12.3 Stabilized IP weights 12.4 ...
- 使用 history 对象和 location 对象中的属性和方法制作一个简易的网页浏览工具
查看本章节 查看作业目录 需求说明: 使用 history 对象和 location 对象中的属性和方法制作一个简易的网页浏览工具 实现思路: 使用history对象中的 forward() 方法和 ...
- Android studio 报错 Unable to resolve dependency for ‘:app@releaseUnitTest/compileClasspath‘:
出现报错: Unable to resolve dependency for ':app@debugAndroidTest/compileClasspath': Could not find any ...
- docker学习:docker命令
帮助命令 自验证 docker version 详情信息 docker info 获取帮助 docker --help 镜像命令 列出本例主机上的镜像 docker images [OPTIONS] ...
- linux 部署.net core 环境
Linux版本Ubuntu 16.04 .net core 下载地址:https://dotnet.microsoft.com/download/dotnet-core/2.1 虽然现在现在.net ...