gin 三.请求数据的映射

2023-11-12

基础解释

  1. 解释: 例如后端获取调用方参数,通常会使用一个结构体,或一个变量来接收,调用方传递的数据会自动映射到该变量上,而不是通过request去手动获取,怎么映射
  2. 目前Gin⽀持JSON、XML、YAML和标准表单值的绑定。就是根据Body数据类型,将数据赋值到指定的结构体变量中 (类似于序列化和反序列化)
  3. go提供了两套绑定方案
  1. Must bind(可以简单理解为当获取参数映射时如果出现错误会panic),** MustBindWith 支持如下方式:** Bind , BindJSON , BindXML , BindQuery , BindYAML,注意点: 如果存在绑定错误,则终⽌请求,使⽤ c.AbortWithError (400) .SetType (ErrorTypeBind) 即可。将响应状态代码设置为400,Content-Type header设置为 text/plain;charset = utf - 8 。如果在此之后设置响应代码,将会受到警告: [GIN-debug[WARNING] Headers were alreadywritten. Wanted to override status code 400 with 422 将导致已经编写了警告[GIN-debug][warning]标头。如果想更好地控制⾏为,可以考虑使⽤ShouldBind等效⽅法
  2. Should bind(可以简单理解为如果出现错误,会将错误返回由开发人员自己处理),ShouldBindWith 支持如下方式: ShouldBind , ShouldBindJSON , ShouldBindXML , ShouldBindQuery , ShouldBindYAML,这些⽅法使⽤ShouldBindWith。如果存在绑定错误,则返回错误,开发⼈员有责任适当地处理请求和错误
    在这里插入图片描述

ShouldBindWith 请求数据映射示例

  1. 在使用映射时要创建对应结构体,例如:(注意点:binding:"required"表示必须的,如果不传,解析映射时会报错)
//如果调用方传递的是form表单,则表单中的key值要与当前结构体中form对应的key值一样
//同理,如果是json或xml也要与当前结构体中json,xml对应的key值一样

//添加 binding:"required" 表示该字段为必须的,如果不传在解析映射时会报错
type Login struct {
	User     string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
	Password string `form:"password" json:"password" uri:"password"xml:"password" binding:"required"`
	//不能为空并且大于10
    Age      int       `form:"age" binding:"required,gt=10"`
    Name     string    `form:"name" binding:"required"`
    Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
}
  1. 在不知道调用方传递的数据类型情况下使用ShouldBind()方法进行解析,示例
package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

type Login struct {
	User     string `form:"username" json:"user" uri:"user" xml:"user"binding:"required"`
	Password string `form:"password" json:"password" uri:"password"xml:"password" binding:"required"`
}

func main() {
	router := gin.Default()
	//1.binding JSON
	// Example for binding JSON ({"user": "ls", "password": "123456"})
	router.POST("/loginJSON", JsonFunc)
	router.Run(":8080")
}

func JsonFunc(c *gin.Context) {

	//1.创建接收参数对应的结构体变量
	var login Login

	//2.在不知道调用方传递的是什么数据类型时使用c.ShouldBindJSON(&login)
	//通过Context调用ShoudBind()方法将创建的对应结构体变量指针传递给该方法
	//方法内部首先在请求头中拿到请求类型,例如MIMEJSON..等等,根据该类型自动
	//选择对应的解析方法进行解析
	if err := c.ShouldBind(&login); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
}
  1. 注意点ShouldBind()查看源码,该方法只支持一下类型,根据Content-Type请求头,获取到指定类型后,按照指定格式获取参数进行绑定调用 ShouldBindWith()方法
func (c *Context) ShouldBind(obj interface{}) error {
	b := binding.Default(c.Request.Method, c.ContentType())
	return c.ShouldBindWith(obj, b)
}

func Default(method, contentType string) Binding {
	if method == http.MethodGet {
		return Form
	}

	switch contentType {
	case MIMEJSON:
		return JSON
	case MIMEXML, MIMEXML2:
		return XML
	case MIMEPROTOBUF:
		return ProtoBuf
	case MIMEMSGPACK, MIMEMSGPACK2:
		return MsgPack
	case MIMEYAML:
		return YAML
	case MIMEMultipartPOSTForm:
		return FormMultipart
	default: // case MIMEPOSTForm:
		return Form
	}
}
  1. 如果明确调用方传递的数据类型,可以直接调用ShouldBindXXX()对应该类型的指定方法进行解析,例如ShouldBindJSON()
if err := c.ShouldBindJSON(&login); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
}

//另外还有
c.ShouldBindXML(&login)
c.ShouldBindYAML(&login)
c.ShouldBindHeader(&login)
c.ShouldBindQuery(&login)
//如果前端使用url参数,例如":8080/test/123/"数据2""",可以使用 c.ShouldBindUri(&login)
c.ShouldBindUri(&login)
  1. 5.gin内部整合了validator库go validator数据校验示例使⽤绑定⽅法时,可以指定参数校验格式,例如使用 binding:“required” 修饰非空等等

ShouldBindHeader 将请求头绑定到一个结构体或接口示例

  1. 可以使用c.ShouldBindHeader方法来将请求头绑定到一个结构体或接口,并使用标签来指定绑定规则
func main() {
	r := gin.Default() // 创建一个默认的gin引擎

	// 定义一个结构体,用来接收请求头中的数据
	type Header struct {
		UserID   string `header:"User-ID"`   // 绑定User-ID字段到UserID属性
		Token    string `header:"Token"`     // 绑定Token字段到Token属性
		ClientIP string `header:"Client-IP"` // 绑定Client-IP字段到ClientIP属性
	}

	// 注册一个GET路由
	r.GET("/info", func(c *gin.Context) {
		// 创建一个Header对象
		var header Header
		// 将请求头绑定到Header对象上
		if err := c.ShouldBindHeader(&header); err != nil {
			// 绑定失败,返回400状态码和错误信息,并终止后续处理
			c.String(400, err.Error())
			c.Abort()
			return
		}

MustBindWith 方式

  1. 与前面的一样也要先创建接收数据对应的结构体变量
  2. 不同的是如果解析失败会panic
  3. 示例
func JsonFunc(c *gin.Context) {

	//1.创建接收参数对应的结构体变量
	var login Login

	//2.c.Bind() 使用的是MustBindWith解析方式,该方式如果解析失败会直接panic将一个400写入响应头中
	//Bind():在不知道调用方数据类型时使用该方法,内部会通过请求头先获取到数据类型然后进行解析
	if err := c.Bind(&login); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if login.User != "ls" || login.Password != "123456" {
		c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
		return
	}
	c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
}

//另外还支持
c.BindJSON(&login)
c.BindXML(&login)
c.BindYAML(&login)
......等等
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

gin 三.请求数据的映射 的相关文章

  • 如何在 HTML 表格上使用分页?

    我正在尝试使用这个分页library http flaviusmatis github io simplePagination js 在我的 HTML 表格页面 特别是浅色主题 中 但不知何故 我无法理解如何在我的 HTML 页面中以这种方
  • 如何在美人鱼节点描述中添加链接?

    我想 如下图所示 div class mermaid graph TD A hello B an b important b link A gt B div 在下面添加实际链接link指向http google com 我尝试将相关节点修改
  • 动态更改 vuejs 2 中的选择输入选项

    如何动态更改选择下拉 v model 中的选项 我有 2 个选择输入 其中一个应该根据其他输入进行更改 例如 如果我选择 水果 则选择显示水果 如果我选择 蔬菜 则选择显示蔬菜 我不使用Vuejs 但查看文档后 var TypesArr F
  • Intro.js 2页然后返回首页

    我在用intro js http introjs com 为我的网站创建一个小介绍 我希望游览从第 1 页 主页 2 另一页 然后回到第 1 页 主页 我已经成功地从第 1 2 页开始 但不确定如何让它返回到第 1 页 我对 javascr
  • 如何使用 poedit 解析 Timber(树枝)模板并检测要翻译的引用字符串

    我想用 poedit 解析 Timber 的树枝模板 并且需要翻译引用的内容 问题是我找不到不跳过引用内容的解析器 Example
  • 在 R Shiny 中,如何使用可排序 js 将其在列表中出现的顺序次数附加到每个列表元素?

    下面的可重现代码适用于将元素从一个面板拖动到另一个面板 并在 拖动到 面板中自动使用 HTML CSS 对拖入的每个元素进行排名顺序编号 但是 我现在尝试附加到每个 拖动到 列表元素的末尾 使用某种形式的paste0 我假设 该元素在 拖至
  • HttpWebRequest vs Webclient(特殊场景)

    我知道这个问题之前已经回答过thread https stackoverflow com questions 1694388 webclient vs httpwebrequest httpwebresponse 但我似乎找不到详细信息 在
  • 加载背景图像的图像不显示

    我真的很困惑 我正在尝试创建一个带有图标和一些按钮的登陆页面 但我无法设法使我正在使用的背景图像显示出来 即使它是根据 Chrome 的开发工具包加载的 我只有这些行 索引 html div class row div class tryh
  • 如何使用 jest 通过 Promise.all 设置多次提取测试

    我在测试中使用 jest 我正在使用 React 和 Redux 并且执行以下操作 function getData id notify return dispatch gt dispatch anotherFunction Promise
  • 如何更改元素的 CSS 类并在单击时删除所有其他类

    我如何处理 AngularJS 2 中的一种情况 即单击一个元素需要更改其自己的样式 并且如果其他元素具有该样式 则需要将其删除 最好在一个函数中 如同Angular js 如何在单击时更改元素 css 类并删除所有其他元素 https s
  • Rails 中的 PDF 导出

    我需要将包含一些图表的 HTML 页面导出为 PDF 有哪些好的 gem 可以做到这一点 PDFKit http railscasts com episodes 220 pdfkit http railscasts com episodes
  • iPhone 点击时使 div 变暗

    当您的 div 附加了点击处理程序时 当点击该 div 时 iPhone 会使该 div 变暗 作为点击指示器 示例 在移动 Safari 上查看http jsbin com awejo3 4 http jsbin com awejo3 4
  • 如何动态隐藏和显示html元素

    html 输入元素使用链接标记隐藏和显示 示例 雅虎邮件密件抄送隐藏和显示 这是用 JavaScript 完成的 对于简单的 Javascript 即不使用jQuery你可以这样做 document getElementById idOfE
  • 如何显示 GroupList 的 FormArray?

    我正在尝试制作一个交互式表单 在每一行上列出一个项目以及一个删除按钮 在我的示例中称为 verwijderen 这些项目是从数据库中检索的 并且每个项目都实例化为名为的自定义对象LaborPeriod 然后这些对象被转化为FormGroup
  • 模拟节点外部模块默认使用 jest 的链式方法

    在我们的节点 CLI 中 我们有一个简单的方法 use strict const ora require ora module exports function startSpinner textOnStart color spinnerT
  • Socket.io 与服务器离线连接

    如何检测服务器是否离线或由于其他原因无法连接 我的代码看起来像这样 this socket io connect connectionInfo reconnect false 它不会抛出任何错误 因此 try catch 子句不起作用 Us
  • 什么是 TinyMCE jQuery 包?

    我被要求在项目中使用 TinyMCE 编辑器 在下载页面上 有一个主包 然后是一个 jQuery 包 This package contains special jQuery build of TinyMCE and a jQuery in
  • 有没有办法从画布上清除一个元素而不消除其他元素?

    我正在使用画布构建页面加载器 并使用 es6 类 虽然目前我无法使其正常工作 原因之一是我找不到清除画布的方法进展 到目前为止 这是我的代码 class Loader constructor width height this width
  • JsGrid 将嵌套对象加载到表中

    我正在 Django 中开发一个 Web 项目并使用 jsGrid 我遇到了问题并且找不到解决方案 我有一个嵌套的 JSON 数据 它是通过组合多个数据库表记录创建的 这是我的 JSON count 3 results personnel
  • 如何调试 Node.js 应用程序?

    如何调试 Node js 服务器应用程序 现在我主要使用警报调试打印语句如下 sys puts sys inspect someVariable 一定有更好的调试方法 我知道谷歌浏览器 http en wikipedia org wiki

随机推荐

  • ESLint: The array literal notation [] is preferable. (no-array-constructor)

    为什么80 的码农都做不了架构师 gt gt gt var xx new Array 改为 var xx 找到一篇不错的文章 总结的不错 https blog csdn net zcfzfc123456789 article details
  • python爬虫-异步爬虫

    注 本文章为学习过程中对知识点的记录 供自己复习使用 也给大家做个参考 如有错误 麻烦指出 大家共同探讨 互相进步 借鉴出处 该文章的路线和主要内容 崔庆才 第2版 python3网络爬虫开发实战 前言 爬虫属于IO密集型任务 例如使用re
  • Windows 命令行

    Windows命令行 1 echo 显示内容 echo 内容 类似log echo on off 打开 关闭回写 echo off 内容 pause 写pause时才进行输出 2 cd 进入目录 cd 内容 path路径 进入到对应的文件夹
  • 函数指针(函数作为参数传递给其他函数)

    函数也有地址 函数的地址是存储其机器码的内存的开始的地址 并且函数的地址就是其函数名 因此我们可以将函数作为参数传递给其他函数 正如python中可以将函数轻易的传递给其他函数一样 但是C 中形式上会复杂一些 声明函数指针 如下我们声明了一
  • Java里的按值传递与引用传递

    这个在Java里面是经常被提起的问题 也有一些争论 似乎最后还有一个所谓的结论 在Java里面参数传递都是按值传递 事实上 这很容易让人迷惑 下面先分别看看什么是按值传递 什么是按引用传递 只要能正确理解 至于称作按什么传递就不是个大问题了
  • 【基于python+flask的葡萄酒数据可视化分析+大屏-哔哩哔哩】 https://b23.tv/3ogTuIl

    基于python flask的葡萄酒数据可视化分析 大屏 哔哩哔哩 https b23 tv 3ogTuIl https b23 tv 3ogTuIl
  • ECharts笔记-------柱状图与折线图

    这幅图表由title legend series xAxis yAxis和tooltip这六个组件组成 每个组件都有对应的属性来调节参数 title和legend的代码跟上一篇一样 这里就不多讲了 tooltip组件 tooltip tri
  • linux命令 移动/复制文件/目录到指定目录下

    1 同一个服务器下复制文件或文件夹 1 1 复制文件 复制文件 把1 txt 复制到根目录下的sbin目录 cp 文件名 可带路径 目标路径 带路径 如 cp 1 txt sbin 1 2 复制目录 复制目录 把release 复制到根目录
  • Jwt安装配置

    1 登录接口 2 刷新接口 3 自定义返回格式 1 JWT安装配置 1 1 安装JWT pip install djangorestframework jwt 1 11 0 1 2 syl settings py 配置jwt载荷中的有效期设
  • CocosCreator 长地图相机渲染不全

    记录一下 浏览器运行的时候用default是没有问题的 一旦给换成其他型号的屏幕尺寸 相机就加载不全 地图宛如断开了一样 但是地图里面的刚体什么的都还在 只是不显示 类似这个样子 搜索了一大圈 大概有这么多的可能 1 地图的图层是否有问题
  • 【华为OD机试】字符串子序列II【2023 B卷

    华为OD机试 真题 点这里 华为OD机试 真题考点分类 点这里 题目描述 给定字符串 target 和 source 判断 target是否为 source 的子序列 你可以认为target和 source 中仅包含英文小写字母 字符串 s
  • 计算机网络安全,你了解多少?

    在现在这个网络高度发达的世界 计算机网络安全便也十分重要 但人们对于它的了解少之又少 今天就让我们一起来了解一下吧 1 什么是计算机网络安全 计算机网络安全是指用网络管理控制和技术措施 保证在一个网络环境里数据的保密性 完整性及可使用性受到
  • Nginx 做成系统服务(windows)

    下载winsw https github com winsw winsw releases 将winsw可执行程序复制到nginx安装目录下 并重命名为nginx service 新建名为nginx service xml的文件 注 文件名
  • CSS中苹果X全面屏的适配问题解决方法

    前言 iPhoneX 取消了物理按键 改成底部小黑条 这一改动导致网页出现了比较尴尬的屏幕适配问题 对于网页而言 顶部 刘海部位 的适配问题浏览器已经做了处理 所以我们只需要关注底部与小黑条的适配问题即可 即常见的吸底导航 返回顶部等各种相
  • 编译OpenWRT 出现error 1 set FORCE_UNSAFE_CONFIGURE=1

    补个博客 最近发现记忆不行了 很多问题重复遇见却不记得之前怎么决绝的 在编译OpenWRT时出现 you should not run configure as root set FORCE UNSAFE CONFIGURE 1 in en
  • 关于51/STC单片机中断优先级的调整

    来源 单片机简单程序 zhjysx的博客 CSDN博客https blog csdn net zhjysx category 11558658 html 目录 内容简述 理论 中断源类型 IP寄存器 LED程序 Proteus仿真图 外部中
  • Django基础入门⑭:Django表单实例【表单应用】获取全量书籍信息

    Django基础入门 Django 对象查询详解 分组聚合 Django表单实例 表单应用 编写模板层HTML页面 编写视图层逻辑代码 配置url路由模式映射 页面搜索效果展示 表单验证逻辑 获取全量书籍信息 实现添加书籍信息 个人简介 以
  • 总结numpy中的ndarray,非常齐全

    总结numpy中的ndarray 非常齐全 numpy Numerical Python 是一个开源的Python数据科学计算库 支持对N维数组和矩阵的操作 用于快速处理任意维度的数组 numpy库的功能非常聚焦 专注于做好 一件事 num
  • 1、树莓派4B设置热点,一步步细心来

    参考了 https www icode9 com content 4 683569 html https zhuanlan zhihu com p 101089893 一定要细心 1 安装 network manager sudo apt
  • gin 三.请求数据的映射

    数据解析绑定 基础解释 ShouldBindWith 请求数据映射示例 ShouldBindHeader 将请求头绑定到一个结构体或接口示例 MustBindWith 方式 基础解释 解释 例如后端获取调用方参数 通常会使用一个结构体 或一