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

两种方式的对比

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

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

小结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/457068.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BUUCTF-Real-ThinkPHP]5.0.23-Rce

漏洞介绍 这个版本容易存在我们都喜欢的rce漏洞! 网站为了提高访问效率往往会将用户访问过的页面存入缓存来减少开销。而Thinkphp 在使用缓存的时候是将数据序列化,然后存进一个 php 文件中,这使得命令执行等行为成为可能! ThinkP…

企业网站管理系统(多语言)

应用介绍 响应式PC: https://demo.ldcms.com.cn/ 响应式H5: 前端小程序: 后台登录网址: https://demo.ldcms.com.cn/ESBFdpKflc.php/index/login 前端截图: 后台截图: 本文来自:企业网站管理…

小白买新电脑保姆验机教程

目录 前言: 正文: 7,查看硬件信息 8,检查硬盘 9,检查屏幕 10,烤机检测 总结: 前言: 最近因为学习的需求,购入了一台新的笔记本,正巧趁这次给身边的朋友…

【Kafka】 存储机制

目录 日志存储结构总体结构LogSegment文件具体结构偏移量索引文件结构时间戳索引文件结构消息日志文件结构 查找 message过程使用偏移量索引文件使用时间戳索引文件 相关配置 日志清除及压缩日志清理基于时间基于日志大小基于偏移量 日志压缩概述日志压缩实现细节 磁盘数据存储…

GPS对时装置、NTP对时服务器、GPS对时装置介绍

而NTP对时服务器是针对计算机、自动化装置等进行校时而研发的高科技设备,该产品可从北斗GPS卫星(CDMA、B码接口、PTP)上获取标准的时间信号,将这些信号通过各种接口(NTP/SNTP、串口、B码、PTP、脉冲)传输给…

【并发编程】手写线程池阻塞队列

📝个人主页:五敷有你 🔥系列专栏:并发编程 ⛺️稳重求进,晒太阳 示意图 步骤1:自定义任务队列 变量定义 用Deque双端队列来承接任务用ReentrantLock 来做锁并声明两个条件变量 Condition fullWai…

debian12 - openssh-9.6.P1的编译安装

文章目录 debian12 - openssh-9.6.P1的编译安装概述笔记备注END debian12 - openssh-9.6.P1的编译安装 概述 在debian12上, 源码编译安装了openssl3.2 导致ssh失败. lostspeeddebian12d4x64:~$ openssl version OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2…

基于SpringBoot开发的校刊投稿系统[附源码]

基于SpringBoot开发的校刊投稿系统[附源码] 🍅 作者主页 央顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各种定制系统 &#x1f…

计算机网络-流量控制(数据链路层的流量控制及与传输层流量控制的区别 流量控制的方法 可靠传输,滑动窗口,流量控制三者关系)

文章目录 数据链路层的流量控制及与传输层流量控制的区别流量控制的方法各方法对应的发生窗口和接收窗口大小 可靠传输,滑动窗口,流量控制三者关系小结 数据链路层的流量控制及与传输层流量控制的区别 端到端:两个主机之间的 点对点&#xf…

蓝桥杯Web应用开发-CSS3 新特性

CSS3 新特性 专栏持续更新中 在前面我们已经学习了元素选择器、id 选择器和类选择器,我们可以通过标签名、id 名、类名给指定元素设置样式。 现在我们继续选择器之旅,学习 CSS3 中新增的三类选择器,分别是: • 属性选择器 • 子…

c++二叉树寒假特训题目(1)

大家好,我是周曦,今天给大家推荐一些二叉树题目。 题目 二叉树存储 这道题是道水题,找找规律ok,本人代码10行。 淘汰赛 这道题推荐使用桶数组 做比较合适(就是有点绕)。 二叉树深度 这题是一道深搜题&a…

安装newman显示required node version >=16解决办法

直接安装对应版本就行,我的Node.js是14.16.0的版本,newman安装5.2.2的就不会出错。 npm install -g newman5.2.2