当前位置: 首页 > news >正文

探索Gin框架:Golang Gin框架请求参数的获取

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站https://www.captainbed.cn/kitie。

前言

我们在专栏的前面几篇文章内讲解了Gin框架的路由配置,服务启动等内容。

专栏地址:https://blog.csdn.net/qq_35716689/category_12575301.html

在我们平常添加路由处理函数之后,就可以在路由处理函数中编写业务处理代码了,但在此之前我们往往需要获取请求参数,本文就详细的讲解下gin获取请求参数常见的几种方式。

目录

前言

传递参数的方式

Header

URL

HTTP Body

直接获取请求参数

获取URL Path中的参数

获取URL Query中的参数

获取HTTP Body中的参数

绑定请求参数

绑定Header参数

绑定URL Path参数

绑定URL Query参数

绑定HTTP Body参数

数据校验

两种方式的对比

小结


传递参数的方式

在一个HTTP请求中,一般可以把上传参数分为以下三个部分:

Header是HTTP请求中一个键值对集合,HTTP规范定义了很多的Headeer,比如Content-Type,Accept等,不过也可以自定义请求头部或者响应头部。

URL

URL指的是请求路径,在请求路径上可以通过两种方式携带请求参数,一种是直接写在请求路径上的,称为URL Path:

http://localhost:8080/user/add

在URL上传递参数的另外一种方式就是URL Query,URL Query参数是指跟在?后面的键值对集合,多个参数之间以&分隔的:

http://localhost:8080/user/add?name=小明&gender=男

HTTP Body

HTTP Body参数是指HTTP请求的请求体所携带的参数,这部分参数会因为Content-Type不同而不同,比如当Content-Type为application/json时,HTTO Body携带的是一串JSON字符串。

那么,在Gin框架中,要如何获取这些请求参数呢?主要有以下两种方式:

  • 直接用Gin封装的方法获取请求参数
  • 通过绑定的方式来获取请求参数

直接获取请求参数

Gin框架在net/http包的基础上封装了获取参数的方式。

获取URL Path中的参数

在路由中使用通配符时,对应的通配符就会成为URL Path参数,调用gin.Context的Param()方法可以获取Path参数:

 package main​func main(){engine := gin.Default()engine.GET("/user/:id", func(ctx *gin.Context) {id := ctx.Param("id")fmt.Fprintf(ctx.Writer, "你的请求id:%s", id)})engine.Run()}

运行后发起请求:

 $ curl http://localhost:8080/user/100你的请求id:100

获取URL Query中的参数

gin.Context对象提供了以下几个主要方法用于获取Query参数:

 package main​import ("fmt"​"github.com/gin-gonic/gin")​func main() {engine := gin.New()engine.GET("/user/list", func(ctx *gin.Context) {//获取单个值name := ctx.Query("name")//带默认值gender := ctx.DefaultQuery("gender", "男")//数组habits := ctx.QueryArray("habits")//mapworks := ctx.QueryMap("works")fmt.Printf("%s,%s,%s,%s\n", name, gender, habits, works)})​engine.Run()}

运行后发起请求:

curl -X GET "http://localhost:8080/user/list?name=John&gender=男&habits[]=reading&habits[]=sports&works[teacher]=math&works[engineer]=computer"
John,男,[reading sports],map[engineer:computer teacher:math]

获取HTTP Body中的参数

对于通过HTTP Body传上来的参数,gin.Context也提供了几种主要方法用于获取:

 package main​import ("fmt"​"github.com/gin-gonic/gin")​func main() {engine := gin.New()engine.POST("/user/add", func(ctx *gin.Context) {//获取单个值name := ctx.PostForm("name")//带默认值gender := ctx.DefaultPostForm("gender", "男")//数组habits := ctx.PostFormArray("habits")//mapworks := ctx.PostFormMap("works")fmt.Printf("%s,%s,%s,%s\n", name, gender, habits, works)})​engine.Run()}

绑定请求参数

Gin支持绑定Header,URL Path,URL Query以及HTTP Body等不同位置数据。

绑定Header参数

绑定Header参数可以使用BindHeader()或者ShouldBindHeader()方法:

 package main​import ("fmt""net/http"​"github.com/gin-gonic/gin")​type testHeader struct {Rate   int    `header:"Rate"`Domain string `header:"Domain"`}​func main() {r := gin.Default()r.GET("/", func(c *gin.Context) {h := testHeader{}​if err := c.ShouldBindHeader(&h); err != nil {c.JSON(http.StatusBadRequest, err)return}​fmt.Printf("%#v\n", h)c.JSON(http.StatusOK, gin.H{"Rate": h.Rate, "Domain": h.Domain})})​r.Run()}

运行后的请求结果:

$ curl -H "rate:300" -H "test:123" http://localhost:8080/
{"Test":"123","Rate":300}

绑定URL Path参数

绑定URL Path参数可以使用BindUri()或者ShouldBindUri()方法:

package mainimport ("fmt""net/http""github.com/gin-gonic/gin"
)type User struct {Name  string `uri:"name"`Email string `uri:"email"`
}func main() {engine := gin.New()engine.GET("/user/list/:email/:name", func(ctx *gin.Context) {var u Userif err := ctx.BindUri(&u);err != nil {ctx.JSON(http.StatusBadRequest, err)return}fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)})engine.Run()
}

运行后的请求结果: 

curl -X GET "http://localhost:8080/user/list/john@163.com/john
你输入的用户名为:john,邮箱为:john@163.com

绑定URL Query参数

绑定URL Query参数可以使用BindQuery()、ShouldBindQury()、Bind()或者ShouldBind()方法:

package mainimport ("fmt""net/http""github.com/gin-gonic/gin"
)type User struct {Name  string `form:"name"`Email string `form:"email"`
}func main() {engine := gin.New()engine.GET("/user/list", func(ctx *gin.Context) {var u Userif err := ctx.BindQuery(&u);err != nil {ctx.JSON(http.StatusBadRequest, err)return}fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)})engine.Run()
}

运行后的请求结果:

curl -X GET "http://localhost:8080/user/list?email=john@163.com&name=john
你输入的用户名为:john,邮箱为:john@163.com

绑定HTTP Body参数

我们知道HTTP Body的参数会根据不同Content-Type传不同格式的数据,Gin支持以下几种Content-Type类型的绑定:

  • JSON
  • XML
  • TOML
  • YAML
  • x-www-form-urlencoded
  • multipart/form-data

注意HTTP Body的数据只在POST请求时才会进行绑定。

绑定HTTP Body参数可以用Bind()和ShouldBind()方法,这两个方法会根据当前请求的Content-Type类型自动判断请求的类型。

package mainimport ("fmt""net/http""github.com/gin-gonic/gin"
)type User struct {Name  stringEmail string
}func main() {engine := gin.New()engine.POST("/user/add", func(ctx *gin.Context) {var u Userif err := ctx.Bind(&u); err != nil {ctx.JSON(http.StatusBadRequest, err.Error())return}fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)})engine.Run()
}

如果明确请求数据的类型,也可以直接调用对应类型绑定的方法,比如确定是JSON格式数据的话,可以调用BindJSON()或者ShouldBindJSON():

package mainimport ("fmt""net/http""github.com/gin-gonic/gin"
)type User struct {Name  stringEmail string
}func main() {engine := gin.New()engine.POST("/user/add", func(ctx *gin.Context) {var u Userif err := ctx.BindJSON(&u); err != nil {ctx.JSON(http.StatusBadRequest, err.Error())return}fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)})engine.Run()
}

对于x-www-form-urlencoded和multipart/form-data,与Qurey参数一样,结构体需要添加form的tag:

package mainimport ("fmt""net/http""github.com/gin-gonic/gin"
)type User struct {Name  string `form:"name"`Email string `form:"email"`
}func main() {engine := gin.New()engine.POST("/user/add", func(ctx *gin.Context) {var u Userif err := ctx.Bind(&u); err != nil {ctx.JSON(http.StatusBadRequest, err.Error())return}fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)})engine.Run()
}

数据校验

在数据绑定的时候,也可以进行数据校验,这里我们为User结构体的标签添加了required属性,要求这个字段必须要有:

package mainimport ("fmt""net/http""github.com/gin-gonic/gin"
)type User struct {Name  string `binding:"required"`Email string `binding:"required"`
}func main() {engine := gin.New()engine.POST("/user/add", func(ctx *gin.Context) {var u Userif err := ctx.Bind(&u); err != nil {ctx.JSON(http.StatusBadRequest, err.Error())return}fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)})engine.Run()
}

两种方式的对比

相较于直接获取请求参数,请求数据绑定是一种更强大且优雅的参数获取方式,使用这种方式获取参数有以下几个好处:

  • 直接将所有参数绑定到一个结构体中,不需要手动一个个地获取参数。
  • 绑定后的参数会自动转换为结构体对应字段的类型,不需要手动对每个参数进行数据类型转换。
  • 在进行数据绑定的同时还可以进行数据校验。

小结

直接获取请求参数虽然没有绑定参数那么强大,但对于简单的请求来说,也是够用的,因此,我们可以根据自己的需求,选择对应的方式来获取请求参数。

相关文章:

探索Gin框架:Golang Gin框架请求参数的获取

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站https://www.captainbed.cn/kitie。 前言 我们在专栏的前面几篇文章内讲解了Gin框架的路由配置,服务启动等内容。 专栏地址&…...

极值图论基础

目录 一,普通子图禁图 二,Turan问题 三,Turan定理、Turan图 1,Turan定理 2,Turan图 四,以完全二部图为禁图的Turan问题 1,最大边数的上界 2,最大边数的下界 五,…...

word导出链接

java 使用 POI 操作 XWPFDocumen 创建和读取 Office Word 文档基础篇 https://www.cnblogs.com/mh-study/p/9747945.html word标签解析文档 http://www.datypic.com/sc/ooxml/e-w_tbl-1.html...

(delphi11最新学习资料) Object Pascal 学习笔记---第4章第2.5节(重载和模糊调用)

4.2.5 重载和模糊调用 ​ 当调用一个重载的函数时,编译器通常会找到匹配的版本并正确工作,或者如果没有任何重载版本具有正确匹配的参数(正如我们刚刚看到的),则会报出错误。 ​ 但还有第三种情况:假设编…...

ElementUI Data:Table 表格

ElementUI安装与使用指南 Table 表格 点击下载learnelementuispringboot项目源码 效果图 el-table.vue&#xff08;Table表格&#xff09;页面效果图 项目里el-table.vue代码 <script> export default {name: el_table,data() {return {tableData: …...

11.2 OpenGL可编程顶点处理:细分着色器

细分 Tessellation Tessellation&#xff08;细分&#xff09;是计算机图形学中的一种技术&#xff0c;用于在渲染过程中提高模型表面的几何细节。它通过在原始图元&#xff08;如三角形、四边形或补丁&#xff09;之间插入新的顶点和边&#xff0c;对图元进行细化分割&#x…...

微软正在偷走你的浏览记录,Edge浏览器偷疯了

虽然现在 Edge 浏览器相当强大&#xff0c;甚至在某种程度上更符合中国用户的使用体验&#xff1b;但最近新的Edge浏览器推出后一直在使用的用户应该有感受到&#xff0c;原本的冰清玉洁的转校生慢慢小鸡脚藏不住了&#xff0c;广告越来越多&#xff0c;越来越流氓了。 电脑之前…...

什么是数据库软删除,什么场景下要用软删除?(go GORM硬删除)

文章目录 什么是数据库软删除&#xff0c;什么场景下要用软删除&#xff1f;go GORM硬删除什么是数据库软删除什么场景下要用软删除 什么是数据库软删除&#xff0c;什么场景下要用软删除&#xff1f; go GORM硬删除 使用的是 GORM&#xff0c;默认启用了软删除功能&#xff…...

计算机设计大赛 深度学习+python+opencv实现动物识别 - 图像识别

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 inception_v3网络5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; *…...

我主编的电子技术实验手册(02)——仪表与电源

本专栏是笔者主编教材&#xff08;图0所示&#xff09;的电子版&#xff0c;依托简易的元器件和仪表安排了30多个实验&#xff0c;主要面向经费不太充足的中高职院校。每个实验都安排了必不可少的【预习知识】&#xff0c;精心设计的【实验步骤】&#xff0c;全面丰富的【思考习…...

C语言----内存函数

内存函数主要用于动态分配和管理内存&#xff0c;它直接从指针的方位上进行操作&#xff0c;可以实现字节单位的操作。 其包含的头文件都是&#xff1a;string.h memcpy copy block of memory的缩写----拷贝内存块 格式&#xff1a; void *memcpy(void *dest, const void …...

【力扣】快乐数,哈希集合 + 快慢指针 + 数学

快乐数原题地址 方法一&#xff1a;哈希集合 定义函数 getNext(n) &#xff0c;返回 n 的所有位的平方和。一直执行 ngetNext(n) &#xff0c;最终只有 2 种可能&#xff1a; n 停留在 1 。无限循环且不为 1 。 证明&#xff1a;情况 1 是存在的&#xff0c;如力扣的示例一…...

c实现顺序表

目录 c语言实现顺序表 完整代码实现 c语言实现顺序表 顺序表的结构定义&#xff1a; typedef struct vector {int size; // 顺序表的容量int count; // 顺序表现在存储了多少个数据int *data; // 指针指向连续的整型存储空间 } vector;顺序表的结构操作&#xff1a; 1、初始…...

微软为新闻编辑行业推出 AI 辅助项目,记者参加免费课程

2 月 6 日消息&#xff0c;微软当地时间 5 日发布新闻稿宣布与多家新闻机构展开多项基于生成式 AI 的合作。微软表示&#xff0c;其使命是确保新闻编辑室在今年和未来拥有创新。 目前建议企业通过微软官方合作伙伴获取服务&#xff0c;可以合规、稳定地提供企业用户使用ChatGP…...

openssl3.2 - exp - buffer to BIO

文章目录 openssl3.2 - exp - buffer to BIO概述笔记END openssl3.2 - exp - buffer to BIO 概述 openssl的资料看的差不多了, 准备将工程中用到的知识点整理一下. openssl中很多API是以操作文件作为输入的, 也有很多API是以BIO作为输入的. 不管文件是不是受保护的, 如果有可…...

Android 13.0 系统framework修改低电量关机值为3%

1、讲在最前面 系统rom定制开发中&#xff0c;其中在低电量时&#xff0c;系统会自动关机&#xff0c;这个和不同的平台和底层驱动和硬件都有关系&#xff0c;需要结合这些来实际调整这个值&#xff0c;我们可以通过分析源码中电池服务的代码&#xff0c;然后进行修改如何实现…...

【EAI 013】BC-Z: Zero-Shot Task Generalization with Robotic Imitation Learning

论文标题&#xff1a;BC-Z: Zero-Shot Task Generalization with Robotic Imitation Learning 论文作者&#xff1a;Eric Jang, Alex Irpan, Mohi Khansari, Daniel Kappler, Frederik Ebert, Corey Lynch, Sergey Levine, Chelsea Finn 论文原文&#xff1a;https://arxiv.org…...

一文讲透ast.literal_eval() eval() json.loads()

文章目录 一文讲透ast.literal_eval() eval() json.loads()1. ast.literal_eval()2. eval()3. json.loads()4. 总结 一文讲透ast.literal_eval() eval() json.loads() 在Python库中&#xff0c;我们经常会遇到需要将字符串转换为相应对象或数据结构的情况。在这种情况下&#…...

微软.NET6开发的C#特性——类、结构体和联合体

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;看到不少初学者在学习编程语言的过程中如此的痛苦&#xff0c;我决定做点什么&#xff0c;下面我就重点讲讲微软.NET6开发人员需要知道的C#特性&#xff0c;然后比较其他各种语言进行认识。 C#经历了多年发展…...

naiveui 上传图片遇到的坑 Upload

我在开发图片上传功能, 需要手动触发上传 但是我调用它内部自定义submit方法, 结果接口一直在报错400 我反反复复的测试了好就, 确定了就是我前端的问题,因为之前一直在做后端的错误排查, 以为是编译问题(因为之前也出现过这个问题) 好 , 我把其中一个参数类型改为String类型, …...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...