Gin框架操作指南06:POST绑定(下)

官方文档地址(中文):https://gin-gonic.com/zh-cn/docs/
注:没用过Gin的读者强烈建议先阅读第一节:Gin操作指南:开山篇。
本节继续演示POST绑定,包括将request-body绑定到不同的结构体中;映射查询字符串或表单参数;上传文件 Query和post-form。

目录

    • 一、将request-body绑定到不同的结构体中
    • 二、映射查询字符串或表单参数
    • 三、上传文件
    • 四、Query和post-form

一、将request-body绑定到不同的结构体中

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

// 定义表单结构体 formA,包含一个必需字段 Foo
type formA struct {
	Foo string `json:"foo" xml:"foo" binding:"required"` // 绑定 JSON 和 XML 的字段 foo
}

// 定义表单结构体 formB,包含一个必需字段 Bar
type formB struct {
	Bar string `json:"bar" xml:"bar" binding:"required"` // 绑定 JSON 和 XML 的字段 bar
}

// 处理请求的函数
func SomeHandler(c *gin.Context) {
	objA := formA{} // 创建 formA 的实例
	objB := formB{} // 创建 formB 的实例

	// c.ShouldBind 使用了 c.Request.Body,不可重用。
	if errA := c.ShouldBind(&objA); errA == nil {
		// 如果绑定成功,返回表单A的成功信息
		c.String(http.StatusOK, `the body should be formA`)
	} else if errB := c.ShouldBind(&objB); errB == nil {
		// 因为现在 c.Request.Body 是 EOF,所以这里会报错。
		c.String(http.StatusOK, `the body should be formB`)
	} else {
		// 处理绑定错误
		c.String(http.StatusBadRequest, `Invalid input`)
	}
}

func main() {
	router := gin.Default()
	router.POST("/some-handler", SomeHandler) // 注册路由
	router.Run(":8080")                       // 启动服务器
}

注意if分支中的注释,效果如下
在这里插入图片描述
在这里插入图片描述
要想多次绑定,可以使用 c.ShouldBindBodyWith.

func SomeHandler(c *gin.Context) {
objA := formA{}
objB := formB{}
// 读取 c.Request.Body 并将结果存入上下文。
if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
c.String(http.StatusOK, the body should be formA)
// 这时, 复用存储在上下文中的 body。
} else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
c.String(http.StatusOK, the body should be formB JSON)
// 可以接受其他格式
} else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
c.String(http.StatusOK, the body should be formB XML)
} else {

}
}
c.ShouldBindBodyWith 会在绑定之前将 body 存储到上下文中。 这会对性能造成轻微影响,如果调用一次就能完成绑定的话,那就不要用这个方法。
只有某些格式需要此功能,如 JSON, XML, MsgPack, ProtoBuf。 对于其他格式, 如 Query, Form, FormPost, FormMultipart 可以多次调用 c.ShouldBind() 而不会造成任任何性能损失 (详见 #1341)。

二、映射查询字符串或表单参数

package main

import (
	"fmt" // 导入格式化I/O库

	"github.com/gin-gonic/gin" // 导入Gin框架
)

func main() {
	router := gin.Default() // 创建默认的Gin路由

	// 设置处理POST请求的路由
	router.POST("/post", func(c *gin.Context) {

		// c.QueryMap("ids") 用于映射查询字符串中的 "ids" 参数
		// 例如:POST /post?ids[a]=1234&ids[b]=hello
		// 这个方法会将查询参数转换为一个map,key为参数名,value为参数值
		ids := c.QueryMap("ids")

		// c.PostFormMap("names") 用于映射表单数据中的 "names" 参数
		// 例如:names[first]=thinkerou&names[second]=tianou
		// 这个方法会将表单数据转换为一个map
		names := c.PostFormMap("names")

		// 打印解析后的 ids 和 names 的值
		// ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
		fmt.Printf("ids: %v; names: %v", ids, names)
	})

	router.Run(":8080") // 启动服务器并监听8080端口
}

打开postman,输入http://localhost:8080/post?ids[a]=1234&ids[b]=hello
然后在body中添加key和value,注意names[]作为一个key,效果如图
在这里插入图片描述

三、上传文件

在”上传文件”,目录下建立两个文件夹demo01和demo02,demo01用于单文件上传:

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	router := gin.Default()
	// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
	// 将内存限制设置为 8 MiB,这意味着如果上传的文件超过这个大小,
	// 将会返回错误,确保服务器不会因为大文件上传而耗尽内存
	router.MaxMultipartMemory = 8 << 20 // 8 MiB

	// 定义一个 POST 路由,处理文件上传
	router.POST("/upload", func(c *gin.Context) {
		// 从请求中获取文件,"file" 是表单字段的名称
		file, err := c.FormFile("file")
		if err != nil {
			// 处理文件获取错误,返回状态码 400 和错误信息
			c.String(http.StatusBadRequest, "Error retrieving the file")
			return
		}

		// 打印文件名到服务器日志
		log.Println(file.Filename)

		// 设置文件保存的目标路径,文件将保存在当前目录下
		dst := "./" + file.Filename
		// 上传文件至指定的完整文件路径
		if err := c.SaveUploadedFile(file, dst); err != nil {
			// 如果文件保存失败,返回状态码 500 和错误信息
			c.String(http.StatusInternalServerError, "Unable to save the file")
			return
		}

		// 返回成功信息,告知用户文件已上传
		c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
	})

	// 启动服务器,监听 8080 端口
	router.Run(":8080")
}

打开postman,输入http://loaclhost:8080/upload,在body中填充form-data,key=file,类型为File,然后选择文件,选好后点击send,效果如下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
多文件上传

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	router := gin.Default()
	// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
	// 将内存限制设置为 8 MiB,这意味着如果上传的文件总大小超过这个限制,
	// 将返回错误,确保服务器不会因为大文件上传而耗尽内存
	router.MaxMultipartMemory = 8 << 20 // 8 MiB

	// 定义一个 POST 路由,用于处理文件上传
	router.POST("/upload", func(c *gin.Context) {
		// Multipart form
		// 从请求中获取 multipart 表单数据
		form, err := c.MultipartForm()
		if err != nil {
			// 如果获取 multipart 表单数据失败,返回状态码 400 和错误信息
			c.String(http.StatusBadRequest, "Failed to get multipart form")
			return
		}

		// 获取上传的文件,"upload[]" 是表单字段的名称
		files := form.File["upload[]"]

		// 遍历每个文件
		for _, file := range files {
			// 打印文件名到服务器日志
			log.Println(file.Filename)

			// 设置文件保存的目标路径,文件将保存在当前目录下
			dst := "./" + file.Filename
			// 上传文件至指定目录
			if err := c.SaveUploadedFile(file, dst); err != nil {
				// 如果文件保存失败,返回状态码 500 和错误信息
				c.String(http.StatusInternalServerError, "Unable to save the file")
				return
			}
		}

		// 返回成功信息,告知用户上传的文件数量
		c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
	})

	// 启动服务器,监听 8080 端口
	router.Run(":8080")
}

在这里插入图片描述

四、Query和post-form

package main

import (
	"fmt"

	"github.com/gin-gonic/gin"
)

func main() {
	// 创建一个新的 Gin 路由引擎
	router := gin.Default()

	// 定义一个 POST 路由,用于处理 POST 请求
	router.POST("/post", func(c *gin.Context) {
		// 从查询字符串中获取 "id" 参数
		id := c.Query("id")
		// 从查询字符串中获取 "page" 参数,如果未提供,则返回默认值 "0"
		page := c.DefaultQuery("page", "0")
		// 从 POST 请求的表单数据中获取 "name" 参数
		name := c.PostForm("name")
		// 从 POST 请求的表单数据中获取 "message" 参数
		message := c.PostForm("message")

		// 打印获取到的参数值到标准输出
		fmt.Printf("id: %s; page: %s; name: %s; message: %s\n", id, page, name, message)
	})

	// 启动 HTTP 服务器,监听 8080 端口
	router.Run(":8080")
}

效果
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小猿口算辅助工具(nodejs版)

github 地址&#xff1a;https://github.com/pbstar/xyks-helper 实现原理 通过屏幕截图截取到题目区域的两个数字&#xff0c;然后通过 ocr 识别出数字&#xff0c;最后通过计算得出答案&#xff0c;并通过模拟鼠标绘制答案。 依赖插件 node-screenshots&#xff1a;屏幕截…

微知-Mellanox驱动中的iSCSI是什么?有哪三种网络存储有哪三种?iSER是什么?(iSCSI协议(总线),SAN 存储区域网络)

背景 本文根据Mellanox网卡驱动中关于iSCSI模块&#xff0c;来介绍iSCSI是什么&#xff1f;该技术发展演进背景&#xff1f; 关于iSCSI iSCSI是一种协议&#xff0c;SCSI是总线。比如常说的SAS&#xff08;Serial Attach SCSI&#xff09;存储盘对比与家用的SATA&#xff0…

Facebook上的隐私保护:如何加强个人数据的安全性?

在数字化时代&#xff0c;个人数据的保护已成为用户日益关注的话题&#xff0c;尤其是在社交媒体平台如Facebook上。用户在享受社交媒体带来的便利时&#xff0c;如何有效保护个人隐私&#xff0c;维护自身的数据安全&#xff0c;成为了一个亟需解决的问题。 Facebook的隐私保护…

算法备案不再难!一篇文章让你成为备案达人

随着互联网的迅猛发展&#xff0c;算法推荐已成为众多互联网信息服务的重要组成部分。然而&#xff0c;算法推荐技术的广泛应用也带来了一系列风险和挑战。为了保障公众利益&#xff0c;规范互联网信息服务算法推荐活动&#xff0c;相关部门出台了《互联网信息服务算法推荐管理…

Dubbo接口级和应用级注册,Dubbo消费者注册到Nacos

学习文档 视频学习 代码演示环境 Dubbo 3.2.9Nacos 2.3.0 一、什么是接口级和应用级 假设有一个服务A&#xff0c;里面提供了2个Dubbo接口XdxOneService、XdxTwoService&#xff0c;Dubbo生产者把服务注册到Nacos&#xff08;或其它的注册中心&#xff09; 以应用级别注册&a…

MySQL之Buffer Pool缓冲池详解

为什么要有 Buffer Pool&#xff1f; 虽然说 MySQL 的数据是存储在磁盘里的&#xff0c;但是也不能每次都从磁盘里面读取数据&#xff0c;这样性能是极差的。 要想提升查询性能&#xff0c;加个缓存就行了嘛。所以&#xff0c;当数据从磁盘中取出后&#xff0c;缓存内存中&am…

软件功能测试重点和流程有哪些?专业软件测评服务公司推荐

软件功能测试就是对产品的各功能进行验证&#xff0c;根据功能测试用例&#xff0c;逐项测试&#xff0c;检查产品是否达到用户要求的功能。功能测试也叫黑盒测试或数据驱动测试&#xff0c;只需考虑需要测试的各个功能&#xff0c;不需要考虑整个软件的内部结构及代码.一般从软…

Unity修改鼠标图片【超简单】

1.向Unity导入需要修改的鼠标图片&#xff0c;在Unity内设置图片的Texture Type为Cursor。 2.编写代码 [SerializeField] Texture2D mouseTex;//放图片 void Start() {Cursor.SetCursor(mouseTex, Vector2.zero, CursorMode.Auto); }3.代码挂载在某物体&#xff08;或者随便哪…

2024年区块链钱包现状与未来趋势分析

钱包作为Web3世界的入口&#xff0c;充当了用户与区块链应用交互、管理资金和传递信息的关键工具。随着区块链技术的发展&#xff0c;钱包生态系统日益多样化&#xff0c;涌现出大量不同类型的解决方案。这些解决方案不仅极大地改善了用户体验&#xff0c;还推动了区块链技术和…

string模拟优化和vector使用

1.简单介绍编码 utf_8变长编码&#xff0c;常用英文字母使用1个字节&#xff0c;对于其它语言可能2到14&#xff0c;大部分编码是utf_8&#xff0c;char_16是编码为utf_16, char_32是编码为utf_32&#xff0c; wchar_t是宽字符的&#xff0c; utf_16是大小为俩个字节&a…

玩转大模型(二)启动一个大模型

写这篇文章是几个月前了&#xff0c;现在模型和框架已经更新了好几轮了&#xff0c;但不影响吧&#xff0c;后面会把这几个月的发展专门用一篇文章补上。 在上一篇中&#xff0c;硬件全都准备好了&#xff0c;软件也已经安装完成&#xff0c;相应的配置都已经做完&#xff0c;…

StarRocks大批量数据导入方案-使用 Kafka connector 导入数据

本文详细介绍如何使用Routine Load 导入数据 一、准备工作 1.1 安装基础环境 主要是安装StarRocks和Kafka&#xff0c;本文直接跳过不做详细介绍~ 二、概念及原理 2.1 概念 导入作业&#xff08;Load job&#xff09; 导入作业会常驻运行&#xff0c;当导入作业的状态为 R…

使用idea和vecode创建vue项目并启动(超详细)

一、idea创建vue项目 创建项目之前先下载好插件 新建项目找到vue生成器 写好名称&#xff0c;找到自己需要存放的地址&#xff0c;node解释器安装方式可以看我上一个博客&#xff0c;vueCLI是选择vue的版本&#xff0c;我们可以使用idea自带的vue版本默认是vue3&#xff0c;创…

SQL注入漏洞(三)

报错注入 group by重复键冲突 &#xff08;count()floor()rand()group by 组合&#xff09;就是利用 count()、rand()、floor()、 group by 这几个特定的函数结合在一起产生的注入漏洞。 ?id1 and (select 1 from (select count(*),concat(0x5e,(select version() from inf…

[含文档+PPT+源码等]精品基于Nodejs实现的微信小程序校园心理健康平台设计与实现

《[含文档PPT源码等]精品基于Nodejs实现的微信小程序校园心理健康平台设计与实现》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等福利&#xff01; 软件开发环境及开发工具&#xff1a; 操作系统&#xff1a;Windows 10、Windows 7、Windows 8 开…

前端excel的实现方案Luckysheet

一、介绍 Luckysheet是一款纯前端类似excel的在线表格&#xff0c;功能强大、配置简单、完全开源的插件。目前已暂停维护&#xff0c;但是其已有功能大概能满足常见需求的使用。 二、引入 ①cdn引入&#xff08;目前应该已经不支持&#xff0c;可自行尝试&#xff09; <l…

mysql 10 单表访问方法

01.优化的过程 对于我们这些 MySQL 的使用者来说&#xff0c; MySQL 其实就是一个软件&#xff0c;平时用的最多的就是查询功能。DBA时不时丢过来一些慢查询语句让优化&#xff0c;我们如果连查询是怎么执行的都不清楚还优化个毛线&#xff0c;所以是时候掌握真正的技术了。我…

LED显示屏与手机连接:简单便捷的操作指南

随着科技的飞速发展&#xff0c;LED显示屏已经成为现代商业和公共信息展示的重要工具。它们不仅在户外广告中扮演着重要角色&#xff0c;室内应用也越来越广泛。智能手机的普及使得我们希望能够通过手机直接控制LED显示屏&#xff0c;以实现更灵活、更便捷的信息展示。那么&…

证件照小程序源码,前后端稳定运行

演示&#xff1a;证寸照制作 运行环境: Linux Nginx PHP >5.6 MySQL>5.6 安装步骤: 1.下载源码上传至你的服务器宝塔面板 2.直接添加站点选择源码目录&#xff0c;新建数据库 3.设置代码执行目录为/web 4.在浏览器中输入你的域名&#xff0c;会提示安装&#xff0c;填写…

5 -《本地部署开源大模型》在Ubuntu 22.04系统下ChatGLM3-6B高效微调实战

在Ubuntu 22.04系统下ChatGLM3-6B高效微调实战 无论是在单机单卡&#xff08;一台机器上只有一块GPU&#xff09;还是单机多卡&#xff08;一台机器上有多块GPU&#xff09;的硬件配置上启动ChatGLM3-6B模型&#xff0c;其前置环境配置和项目文件是相同的。如果大家对配置过程还…