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

news2024/10/22 21:28:16

官方文档地址(中文):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")
}

效果
在这里插入图片描述

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

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

相关文章

idea删除git历史提交记录

前言&#xff1a;此文章是我在实际工作中有效解决问题的方法&#xff0c;做记录的同时也供大家参考&#xff01; 一、 首先&#xff0c;通过idea的终端或系统的cmd控制台&#xff0c;进入到你的项目文件根目录&#xff0c;idea终端默认就是项目根目录。 二、确保你当前处于要删…

浙大恩特CRM Quotegask_editAction SQL注入漏洞复现

0x01 产品描述&#xff1a; 浙大恩特CRM是由浙江大学恩智浙大科技有限公司推出的客户关系管理&#xff08;CRM&#xff09;系统。该系统旨在帮助企业高效管理客户关系&#xff0c;提升销售业绩&#xff0c;促进市场营销和客户服务的优化。 0x02 漏洞描述&#xff1a; 浙大恩特…

​​Spring6梳理19——基于注解管理Bean之@Autowired注入

以上笔记来源&#xff1a; 尚硅谷Spring零基础入门到进阶&#xff0c;一套搞定spring6全套视频教程&#xff08;源码级讲解&#xff09;https://www.bilibili.com/video/BV1kR4y1b7Qc 目录 19.1 Autowired注入 ①场景一&#xff1a;属性注入 19.1.1创建UserDao接口 19.1.2…

如何将数据从 AWS S3 导入到 Elastic Cloud - 第 2 部分:Elastic Agent

作者&#xff1a;来自 Elastic Hemendra Singh Lodhi 了解将数据从 AWS S3 提取到 Elastic Cloud 的不同选项。 这是多部分博客系列的第二部分&#xff0c;探讨了将数据从 AWS S3 提取到 Elastic Cloud 的不同选项。 在本博客中&#xff0c;我们将了解如何使用 Elastic Agent…

OQE-OPTICAL AND QUANTUM ELECTRONICS

文章目录 一、征稿简介二、重要信息三、服务简述四、投稿须知五、联系咨询 一、征稿简介 二、重要信息 期刊官网&#xff1a;https://ais.cn/u/3eEJNv 三、服务简述 四、投稿须知 1.在线投稿&#xff1a;由艾思科蓝支持在线投稿&#xff0c;请将文章全文投稿至艾思科蓝投稿系…

【Linux】————动静态库

作者主页&#xff1a; 作者主页 本篇博客专栏&#xff1a;Linux 创作时间 &#xff1a;2024年10月22日 一&#xff0e;库的定义 什么是库&#xff0c;在windows平台和linux平台下都大量存在着库。 本质上来说库是一种可执行代码的二进制形式&#xff0c;可以被操作系统载…

虚拟机网络设置为桥接模式

1、打开VMware Workstation Pro&#xff0c;点击“虚拟机—设置”&#xff0c;进入虚拟机设置页面 2、点击“网络适配器”&#xff0c;网络连接选择桥接模式 3、点击“编辑—虚拟网络编辑器”&#xff0c;进入虚拟网络编辑器页面 4、选择桥接模式&#xff0c;并选择要桥接到的…

Flux.using 使用说明书

using public static <T,D> Flux<T> using(Callable<? extends D> resourceSupplier,Function<? super D,? extends Publisher<? extends T>> sourceSupplier,Consumer<? super D> resourceCleanup)Uses a resource, generated by a…

创建人物状态栏

接下来&#xff0c;我们来尝试制作一下我们的UI&#xff0c;我们会学习unity基本的UI系统 ************************************************************************************************************** 我们要先安装一个好用的插件到我们的unity当中&#xff0c;帮助…

Mac电脑:资源库Library里找不到WebServer问题的解决

今天看到一本书里写到Windows电脑自带IIS Web服务器&#xff0c;好奇了一下下&#xff0c;mac电脑自带的又是什么服务器呢&#xff1f;经查询&#xff0c;原来是Apache服务器&#xff0c;这个名字我很熟悉。只是如何设置呢&#xff1f;我从来没用过&#xff0c;于是试验了一番。…

[Linux进程概念]命令行参数|环境变量

目录 一、命令行参数 1.什么是命令行参数 2.为什么要有命令行参数 &#xff08;1&#xff09;书写的代码段 &#xff08;2&#xff09;实际的代码段 3.Linux中的命令行参数 二、环境变量 1.什么是环境变量&#xff1f; 2.获取环境变量 &#xff08;1&#xff09;指令…

OceanBase 的写盘与传统数据库有什么不同?

背景 在数据库开发过程中&#xff0c;“写盘”是一项核心操作&#xff0c;即将内存中暂存的数据安全地转储到磁盘上。在诸如MySQL这样的传统数据库管理系统中&#xff0c;写盘主要有以下几步&#xff1a;首先将数据写入缓存池&#xff1b;其次&#xff0c;为了确保数据的完整性…

【Qt】控件——Qt输入类控件、常见的输入类控件、输入类控件的使用、Line Edit、Text Edit、Combo Box、Spin Box

文章目录 Qt5. Qt显示类控件Line EditText EditCombo BoxSpin BoxQDateTimeEditDialSlider Qt 5. Qt显示类控件 Line Edit QLineEdit 用于表示单行输入框。可以输入一段文本&#xff0c;但是不能换行。 属性说明text输入框中的文本inputMask输入内容格式约束maxLength最大长度…

【HAD】Half-Truth: A Partially Fake Audio Detection Dataset

文章目录 Half-Truth: A Partially Fake Audio Detection Dataset背景key points研究数据集设计评价指标实验基线:utterance-level分类(话语级)基线:segment-level分类(片段级)Half-Truth: A Partially Fake Audio Detection Dataset 会议/期刊:Interspeech 2021 CCF-C…

哈佛医学生一个月吃720个鸡蛋,结果发现......

你们听说过吃鸡蛋还能降低胆固醇的操作吗&#xff1f; 前段时间&#xff0c;哈佛医学院的学生尼克诺尔维茨&#xff08;Nick Norwitz&#xff09;就做了这样一个实验&#xff0c;得出的结果让大家震惊&#xff01; 许多人认为狂吃鸡蛋不会有好处&#xff0c;因为这会摄入大量胆…

FFT过程中自动补零,补零部分FFT结果不为零

在 FFT&#xff08;快速傅里叶变换&#xff09; 中&#xff0c;补零&#xff08;Zero Padding&#xff09;是为了使信号的点数符合 2 的幂次方&#xff0c;以提高 FFT 的计算效率。然而&#xff0c;即使你对信号进行了补零&#xff0c;FFT 计算后在补零部分可能会得到复数结果不…

<项目代码>YOLOv8工具识别<目标检测>

YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv8具有更高的…

数字化营销助企业在生态平台实现内卷突围

在当今数字化时代&#xff0c;企业竞争激烈&#xff0c;内卷化严重。而数字化生态平台建设与数字化营销为企业带来了新机遇。 数字化生态平台意义重大。它能整合企业内外资源&#xff0c;提高运营效率。打破地域限制&#xff0c;拓展市场&#xff0c;吸引更多客户。还能为企业创…

TCP——Socket

应用进程只借助Socket API发和收但是不关心他是怎么进行传和收的 数据结构 图示Socket连接 捆绑属于隐式捆绑

如何快速解决谷歌网站页面收录难题?

在外贸网站的运营中&#xff0c;页面无法被谷歌收录是一个常见的困扰。即便你的内容再优秀&#xff0c;如果搜索引擎的爬虫无法抓取到你的页面&#xff0c;那一切努力都将白费。而GPC爬虫池服务可以帮助你快速解决网站页面的收录问题。它通过千万级的爬虫池资源&#xff0c;强力…