58.Gin参数读取、绑定、文件上传

文章目录

  • 一、RESTful API
  • 二、Gin获取各种方式传递过来的参数
    • 1、获取querystring参数
    • 2、获取form参数
    • 3、获取path参数
  • 三、参数绑定
  • 四、文件上传
    • 1、单个文件上传
    • 2、多个文件上传

Gin框架在我之前的博客中已经使用过很多次了,但是没有集中介绍过参数读取和绑定等知识,这里总结记录一下。

一、RESTful API

REST与技术无关,代表的是一种软件架构风格,RESTRepresentational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”。

简单来说,REST的含义就是客户端与Web服务器之间进行交互的时候,使用HTTP协议中的4个请求方法代表不同的动作。

  • GET用来获取资源

  • POST用来新建资源

  • PUT用来更新资源

  • DELETE用来删除资源。

只要API程序遵循了REST风格,那就可以称其为RESTful API。目前在前后端分离的架构中,前后端基本都是通过RESTful API来进行交互。

例如,我们现在要编写一个管理书籍的系统,我们可以查询对一本书进行查询、创建、更新和删除等操作,我们在编写程序的时候就要设计客户端浏览器与我们Web服务端交互的方式和路径。按照经验我们通常会设计成如下模式:

请求方法URL含义
GET/book查询书籍信息
POST/create_book创建书籍记录
POST/update_book更新书籍信息
POST/delete_book删除书籍信息

同样的需求我们按照RESTful API设计如下:

请求方法URL含义
GET/book查询书籍信息
POST/book创建书籍记录
Put/book更新书籍信息
Delete/book删除书籍信息

Gin框架支持开发RESTful API的开发。

func main() {r := gin.Default()r.GET("/book", func(c *gin.Context) {c.JSON(200, gin.H{"message": "GET",})})r.POST("/book", func(c *gin.Context) {c.JSON(200, gin.H{"message": "POST",})})r.PUT("/book", func(c *gin.Context) {c.JSON(200, gin.H{"message": "PUT",})})r.DELETE("/book", func(c *gin.Context) {c.JSON(200, gin.H{"message": "DELETE",})})
}

此外,还有一个可以匹配所有请求方法的Any方法如下:

r.Any("/test", func(c *gin.Context) {...})

为没有配置处理函数的路由添加处理程序,默认情况下它返回404代码,下面的代码为没有匹配到路由的请求都返回views/404.html页面。

r.NoRoute(func(c *gin.Context) {c.HTML(http.StatusNotFound, "views/404.html", nil)})

开发RESTful API的时候我们通常使用Postman来作为客户端的测试工具。

二、Gin获取各种方式传递过来的参数

1、获取querystring参数

querystring指的是URL?后面携带的参数,例如:/user/search?username=lym&address=北京

获取请求的querystring参数的方法如下:

func main() {//Default返回一个默认的路由引擎r := gin.Default()r.GET("/user/search", func(c *gin.Context) {// DefaultPostForm取不到值时会返回指定的默认值username := c.DefaultQuery("username", "lym")//username := c.Query("username")address := c.Query("address")//输出json结果给调用方c.JSON(http.StatusOK, gin.H{"message":  "ok","username": username,"address":  address,})})r.Run()
}

2、获取form参数

请求的数据通过form表单来提交,例如向/user/search发送一个POST请求

获取请求数据的方式如下:

func main() {//Default返回一个默认的路由引擎r := gin.Default()r.POST("/user/search", func(c *gin.Context) {// DefaultPostForm取不到值时会返回指定的默认值//username := c.DefaultPostForm("username", "lym")username := c.PostForm("username")address := c.PostForm("address")//输出json结果给调用方c.JSON(http.StatusOK, gin.H{"message":  "ok","username": username,"address":  address,})})r.Run(":8080")
}

3、获取path参数

请求的参数通过URL路径传递,例如:/user/search/lym/北京

获取请求URL路径中的参数的方式如下。

func main() {//Default返回一个默认的路由引擎r := gin.Default()r.GET("/user/search/:username/:address", func(c *gin.Context) {username := c.Param("username")address := c.Param("address")//输出json结果给调用方c.JSON(http.StatusOK, gin.H{"message":  "ok","username": username,"address":  address,})})r.Run(":8080")
}

三、参数绑定

为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的Content-Type识别请求数据类型并利用反射机制自动提取请求中QueryStringform表单JSONXML等参数到结构体中。

下面的示例代码演示了.ShouldBind()强大的功能,它能够基于请求自动提取JSONform表单QueryString类型的数据,并把值绑定到指定的结构体对象。

// Binding from JSON
type Login struct {User     string `form:"user" json:"user" binding:"required"`Password string `form:"password" json:"password" binding:"required"`
}func main() {router := gin.Default()// 绑定JSON的示例 ({"user": "lym", "password": "123456"})router.POST("/loginJSON", func(c *gin.Context) {var login Login// ShouldBind()会根据请求的Content-Type自行选择绑定器if err := c.ShouldBind(&login); err == nil {fmt.Printf("login info:%#v\n", login)c.JSON(http.StatusOK, gin.H{"user":     login.User,"password": login.Password,})} else {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})}})// 绑定form表单示例 (user=lym&password=123456)router.POST("/loginForm", func(c *gin.Context) {var login Login// ShouldBind()会根据请求的Content-Type自行选择绑定器if err := c.ShouldBind(&login); err == nil {c.JSON(http.StatusOK, gin.H{"user":     login.User,"password": login.Password,})} else {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})}})// 绑定QueryString示例 (/loginQuery?user=q1mi&password=123456)router.GET("/loginQuery", func(c *gin.Context) {var login Login// ShouldBind()会根据请求的Content-Type自行选择绑定器if err := c.ShouldBind(&login); err == nil {c.JSON(http.StatusOK, gin.H{"user":     login.User,"password": login.Password,})} else {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})}})// Listen and serve on 0.0.0.0:8080router.Run(":8080")
}

ShouldBind会按照下面的顺序解析请求中的数据完成绑定:

  • 如果是 GET 请求,只使用 Form 绑定引擎(query)。

  • 如果是 POST 请求,首先检查 content-type 是否为 JSON XML,然后再使用 Form(form-data)。

四、文件上传

1、单个文件上传

func main() {router := gin.Default()// 处理multipart forms提交文件时默认的内存限制是32 MiB// 可以通过下面的方式修改// router.MaxMultipartMemory = 8 << 20  // 8 MiBrouter.POST("/upload", func(c *gin.Context) {// 单个文件file, err := c.FormFile("file")if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error(),})return}log.Println(file.Filename)dst := fmt.Sprintf("C:/tmp/%s", file.Filename)// 上传文件到指定的目录c.SaveUploadedFile(file, dst)c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("'%s' uploaded!", file.Filename),})})router.Run()
}

2、多个文件上传

func main() {router := gin.Default()// 处理multipart forms提交文件时默认的内存限制是32 MiB// 可以通过下面的方式修改// router.MaxMultipartMemory = 8 << 20  // 8 MiBrouter.POST("/upload", func(c *gin.Context) {// Multipart formform, _ := c.MultipartForm()files := form.File["file"]for index, file := range files {log.Println(file.Filename)dst := fmt.Sprintf("C:/tmp/%s_%d", file.Filename, index)// 上传文件到指定的目录c.SaveUploadedFile(file, dst)}c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("%d files uploaded!", len(files)),})})router.Run()
}

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

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

相关文章

AR眼镜_AR智能眼镜整机硬件方案定制

AR眼镜的主要模块包括显示、光学模组、传感器和摄像头、主板、音频和网络连接等。其中&#xff0c;光学显示、主板处理器是决定AR眼镜成本的关键&#xff0c;光机占整体AR眼镜成本43%、处理器占整体成本31%。 AR眼镜的主板设计难点在于尺寸要足够小且要处理好散热问题。主板上的…

接口优先于反射机制

在Java中&#xff0c;使用接口通常比反射机制更为优雅和安全。接口提供了一种声明性的方式来定义类的契约&#xff0c;并且能够在编译时进行类型检查&#xff0c;而反射则是在运行时动态获取和操作类的信息。下面是一个简单的例子&#xff0c;说明为什么在某些情况下接口比反射…

服务端监控工具:Nmon使用方法

一、认识nmon 1、简介 nmon是一种在AIX与各种Linux操作系统上广泛使用的监控与分析工具&#xff0c;它能在系统运行过程中实时地捕捉系统资源的使用情况&#xff0c;记录的信息比较全面&#xff0c; 并且能输出结果到文件中&#xff0c;然后通过nmon_analyzer工具产生数据文件…

【JavaEE】多线程(4) -- 单例模式

目录 什么是设计模式? 1.饿汉模式 2.懒汉模式 线程安全问题 什么是设计模式? 设计模式好⽐象棋中的 "棋谱". 红⽅当头炮, ⿊⽅⻢来跳. 针对红⽅的⼀些⾛法, ⿊⽅应招的时候有⼀ 些固定的套路. 按照套路来⾛局势就不会吃亏. 软件开发中也有很多常⻅的 "问题…

Mybatis中的${}和#{}区别

前言 动态 sql 是 mybatis 的主要特性之一&#xff0c;在 mapper 中定义的参数传到 xml 中之后&#xff0c;在查询之前&#xff0c; mybatis 会对其进行动态解析。mybatis 为我们提供了两种支持动态 sql 的语法&#xff1a;#{}以及${} 提示&#xff1a;以下是本篇文章正文内容…

【c++】string的模拟实现

目录 一. 交换函数swap 二. 默认成员函数 构造函数和析构函数 拷贝构造函数和赋值运算符重载 三. 容量相关操作接口 size 与 capacity reserve 与 resize 附&#xff1a;reserve与resize的区别 四. 修改相关操作接口 push_pack append insert 与 erase operato…

软件设计师——数据结构(一)

&#x1f4d1;前言 本文主要是【数据结构】——软件设计师——数据结构的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304…

Flink系列之:窗口Top-N

Flink系列之&#xff1a;窗口Top-N 一、窗口Top-N二、示例&#xff1a;在窗口聚合后进行窗口 Top-N三、在窗口表值函数后进行窗口 Top-N四、限制 一、窗口Top-N 适用于流、批一体窗口 Top-N 是特殊的 Top-N&#xff0c;它返回每个分区键的每个窗口的N个最小或最大值。与普通To…

时序分解 | Matlab实现DBO-VMD基于蜣螂优化算法优化VMD变分模态分解时间序列信号分解

时序分解 | Matlab实现DBO-VMD基于蜣螂优化算法优化VMD变分模态分解时间序列信号分解 目录 时序分解 | Matlab实现DBO-VMD基于蜣螂优化算法优化VMD变分模态分解时间序列信号分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.利用蜣螂优化算法优化VMD中的参数k、a&…

12、Kafka中位移提交那些事儿

Kafka中位移提交那些事儿 1、自动提交位移2、手动提交位移2.1、同步提交位移2.2、异步提交位移2.3、更精细化的位移管理 Consumer 端有个位移的概念&#xff0c;它和消息在分区中的位移不是一回事儿&#xff0c;虽然它们的英文都是 Offset。今天我们要聊的位移是 Consumer 的消…

千亿露酒市场的未来之“露”

执笔 | 尼 奥 编辑 | 扬 灵 12月15日&#xff0c;以“以美为酿&#xff0c;品致未来”为主题的中国露酒产业发展大会暨露酒价值论坛在“中国酒都”宜宾举办。 近年来&#xff0c;露酒产业发展异军突起&#xff0c;市场销售规模超越黄酒、葡萄酒品类&#xff0c;成为中国酒…

正则表达式IP地址

正则表达式基础语法 正则表达式-字符类 [abc]&#xff1a;代表a或者b&#xff0c;或者c字符中的一个。 [^abc]&#xff1a;代表除a,b,c以外的任何字符。 [a-z]&#xff1a;代表a-z的所有小写字符中的一个。 [A-Z]&#xff1a;代表A-Z的所有大写字符中的一个。 [0-9]&#xff…

人工智能文本分类

在本文中&#xff0c;我们全面探讨了文本分类技术的发展历程、基本原理、关键技术、深度学习的应用&#xff0c;以及从RNN到Transformer的技术演进。文章详细介绍了各种模型的原理和实战应用&#xff0c;旨在提供对文本分类技术深入理解的全面视角。 一、引言 文本分类作为人工…

期末总复习(重点!!!)

一、第6章异常处理 1、什么是异常、什么是异常处理异常是指程序在运行过程中发生的错误事件&#xff0c;影响程序的正常执行。异常并不是一定会发生&#xff0c;默认情况下&#xff0c;程序运行中遇到异常时将会终止&#xff0c;并在控制台打印出异常出现的堆栈信息。异常处理…

在线客服系统定价因素解析:影响价格的关键因素

跨境电子商务公司必不可少的工具就是在线客服系统。企业选择在线客服系统的时候免不了要对不同产品的功能性、价格、服务等因素进行考量。今天这篇文章&#xff0c;我们就来探讨一下在线客服系统的定价因素有哪些&#xff1f;探究市面上的在线客服系统价格各异的影响因素。为大…

Lambda 的表达式作用域(Lambda Scopes)

文章目录 讲一下 Lambda 的表达式作用域&#xff08;Lambda Scopes&#xff09;。访问局部变量访问字段和静态变量访问默认接口方法 讲一下 Lambda 的表达式作用域&#xff08;Lambda Scopes&#xff09;。 访问局部变量 我们可以直接在 lambda 表达式中访问外部的局部变量&a…

c# bitmap压缩导致png不透明的问题解决

新建.net 6控制台项目 安装System.Drawing.Common包 代码如下 using System.Drawing; using System.Drawing.Imaging;namespace PngCompress02 {internal class Program{static void Main(string[] args){CompressPngImage("E:\Desktop\6.png", "E:\Desktop\6…

C++相关闲碎记录(14)

1、数值算法 &#xff08;1&#xff09;运算后产生结果accumulate() #include "algostuff.hpp"using namespace std;int main() {vector<int> coll;INSERT_ELEMENTS(coll, 1, 9);PRINT_ELEMENTS(coll);cout << "sum: " << accumulate(…

DPDK系列之三十九控制管理

一、基础介绍 通过前面的分析&#xff0c;对DPDK中对报文处理的过程有了一个初步的认知。从一个更高层次来看&#xff0c;传统的网络通信一般会通过上层应用、操作系统、网卡驱动和硬件四层。再往下&#xff0c;基本就不属于于计算机控制的系统了。 早期的应用&#xff0c;基本…

Python - coverage

coverage overage 是一个用于测量Python程序代码覆盖率的工具。它监视您的程序&#xff0c;注意代码的哪些部分已经执行&#xff0c;然后分析源代码&#xff0c;以确定哪些代码本可以执行&#xff0c;但没有执行。 覆盖率测量通常用于衡量测试的有效性。它可以显示代码的哪些…