golang,gin框架的请求参数(一)--推荐

golang,gin框架的请求参数(一)

gin框架的重要性不过多的强调,重点就gin使用中的参数传递,获取进行梳理文件,满足使用需求。

获取前端请求参数的几种方法:

一、获取参数【浏览器地址获取参数】

1.浏览器地址栏获取参数

1.获取 URL (query)参数

例如:/user/search?username=zhangsan&address=北京。 获取请求的query参数的方法如下:
URL 参数可以通过DefaultQuery() 和 Query() 两个参数获取

这两个【DefaultQuery() 和 Query() 】的区别就是,DefaultQuery()可以放个默认参数,如果没有存参数那么就是使用默认参数,

Query()如果不给参数,就是默认为“”

示例:

1.1后端代码:

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

// /user/search?username=zhangsan&address=北京
// urlQuery 获取 url中?后面携带的参数
func urlQueryHandle(ctx *gin.Context) {
	// 如果指定的key 没有对应的值就使用默认值
	username1 := ctx.DefaultQuery("username", "lisi")

	// 根据key 获取值
	username2 := ctx.Query("username")

	address := ctx.Query("address")

	// 返回JSON 字符串
	ctx.JSON(http.StatusOK, gin.H{
		"message":   "ok",
		"username1": username1,
		"username2": username2,
		"address":   address,
	})
}
func main() {

	// 创建默认路由
	r := gin.Default()

	// 绑定路由规则
	r.GET("/user/search", urlQueryHandle)

	// 监听端口
	r.Run(":9000")
}

1.2浏览器访问,从中可以看到我们没有给任何参数,后端Query查询的都是为“”

 1.3带参数的访问

http://127.0.0.1:9000/user/search?username=tom&address=xian&username=jerry

?username=tom&address=xian&username=jerry

 

 1.3.1postman获取参数

 


2.获取参数【获取Path参数(RestFul风格)】

请求的参数通过URL路径传递,例如:/user/search/lisi/北京。 获取请求URL路径中的参数的方式如下。

 

 以下代码是上述两种浏览器获取参数的办法,具体看代码品味下;

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

// /user/search?username=zhangsan&address=北京
// urlQuery 获取 url中?后面携带的参数
func urlQueryHandle(ctx *gin.Context) {
	// 如果指定的key 没有对应的值就使用默认值
	username1 := ctx.DefaultQuery("username", "lisi")

	// 根据key 获取值
	username2 := ctx.Query("username")

	address := ctx.Query("address")

	// 返回JSON 字符串
	ctx.JSON(http.StatusOK, gin.H{
		"message":   "ok",
		"username1": username1,
		"username2": username2,
		"address":   address,
	})
}

// /user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
// paramsPathHandle 获取url path中参数
func paramsPathHandle(ctx *gin.Context) {

	// 获取参数值
	username := ctx.Param("username")
	address := ctx.Param("address")

	// 数据返回
	ctx.JSON(http.StatusOK, gin.H{
		"message":  "ok",
		"username": username,
		"address":  address,
	})
}

func main() {

	// 创建默认路由
	r := gin.Default()
	//两种浏览器地址获取参数的办法
	// 绑定路由规则 /user/search?username=zhangsan&address=北京
	r.GET("/user/search", urlQueryHandle)
	// 2. 绑定路由规则/user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
	r.GET("/user/search/:username/:address", paramsPathHandle)

	// 监听端口
	r.Run(":9000")
}

二、表单获取参数获取 Form参数

表单提交POST请求时,http常见的传输格式有四种application/json (json格式)

  • text/plain (text格式)
  • application/x-www-form-urlencode(表单默认提交格式)
  • application./xml (xml格式)
  • multipart/form-data( 文件上传)

可以通过 DefaultPostForm() 和 PostForm() 两个方法获取(默认解析的是 x-www-form-urlencode 和 form-data 格式的参数)

2.1获取form表单数据

2.1.1application/x-www-form-urlencode(表单默认提交格式)

因为发起post请求,前端只能用postman模拟了

 返回结果

 2.1.2form-data表单提交方式

 

 

2.2获取json参数【ctx.GetRowData()

2.2.1请求数据application./json(json格式)

2.2.2 application./xml (xml格式)

 

  2.3文件上传事项

2.3.1文件上传接收的文件格式要求:

格式是: multipart/form-data

 

2.3.2多文件上传

 

 2.4表单数据获取的代码

package main

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
)

// /user/search?username=zhangsan&address=北京
// urlQuery 获取 url中?后面携带的参数
func urlQueryHandle(ctx *gin.Context) {
	// 如果指定的key 没有对应的值就使用默认值
	username1 := ctx.DefaultQuery("username", "lisi")

	// 根据key 获取值
	username2 := ctx.Query("username")

	address := ctx.Query("address")

	// 返回JSON 字符串
	ctx.JSON(http.StatusOK, gin.H{
		"message":   "ok",
		"username1": username1,
		"username2": username2,
		"address":   address,
	})
}

// /user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
// paramsPathHandle 获取url path中参数
func paramsPathHandle(ctx *gin.Context) {

	// 获取参数值
	username := ctx.Param("username")
	address := ctx.Param("address")

	// 数据返回
	ctx.JSON(http.StatusOK, gin.H{
		"message":  "ok",
		"username": username,
		"address":  address,
	})
}

//=================================

// formParamsHandle 获取form表单提交数据
func formParamsHandle(ctx *gin.Context) {

	// 获取不到值时就是用默认值
	username1 := ctx.DefaultPostForm("username", "lisi")

	username2 := ctx.PostForm("username")
	address := ctx.PostForm("address")

	// 以Json 字符串的形式返回
	ctx.JSON(http.StatusOK, gin.H{
		"message":   "ok",
		"username1": username1,
		"username2": username2,
		"address":   address,
	})
}

// json参数
// paramsJsonHandle 获取json字符串相关的参数
func paramsJsonHandle(ctx *gin.Context) {

	// 获取request.Body() 中的数据(这里没有进行错误处理)
	// 返回的是字节数组
	dataBytes, _ := ctx.GetRawData()

	// 定义一个map
	var m map[string]interface{}

	// 反序列化 别忘了&
	_ = json.Unmarshal(dataBytes, &m)

	// 数据返回
	ctx.JSON(http.StatusOK, m)

}

//文件上传
/*
  单个文件上传
    文件上传接收的文件格式是: multipart/form-data
*/

// singleFileUploadHandle 当文件上传
func singleFileUploadHandle(ctx *gin.Context) {

	// 获取文件
	// 根据上传时的参数名获取上传的文件内容 --> 返回对象为 *multipart.FileHeader
	fileHeader, err := ctx.FormFile("file")
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"message": err.Error(),
		})
		return
	}

	// 保存文件内容
	// 拼接文件名, 这里直接写死了
	targetFileName := fmt.Sprintf("C:/Users/黑熊精/Pictures/%s", fileHeader.Filename)
	//targetFileName := fmt.Sprintf("%s", fileHeader.Filename)

	// 将文件保存到指定的目录
	err = ctx.SaveUploadedFile(fileHeader, targetFileName)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"message": err.Error(),
		})
	} else {
		ctx.JSON(http.StatusOK, gin.H{
			"message": fmt.Sprintf("%s upload success!", fileHeader.Filename),
		})
	}
}

//多文件上传

/**
  多文件上传
*/

// multiFileUploadHandle 多文件上传
func multiFileUploadHandle(ctx *gin.Context) {

	// form 是一个存储文件信息的结构体
	/**
	  type Form struct {
		Value map[string][]string
		File  map[string][]*FileHeader
	*/
	form, err := ctx.MultipartForm()
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"message": err.Error(),
		})
		return
	}

	// 获取文件列表,并保存, 返回的是一个切片 []*FileHeader
	files := form.File["file"]
	for i, file := range files {
		targetFileName := fmt.Sprintf("C:/Users/黑熊精/Pictures/%d_%s", i, file.Filename)
		err = ctx.SaveUploadedFile(file, targetFileName)

		if err != nil {
			ctx.JSON(http.StatusInternalServerError, gin.H{
				"message": err.Error(),
			})
			return
		}
	}
	ctx.JSON(http.StatusOK, gin.H{
		"message": fmt.Sprintf("upload success!"),
	})
}

func main() {

	// 创建默认路由
	r := gin.Default()
	//两种浏览器地址获取参数的办法
	// 绑定路由规则 /user/search?username=zhangsan&address=北京
	r.GET("/user/search", urlQueryHandle)
	// 2. 绑定路由规则/user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
	r.GET("/user/search/:username/:address", paramsPathHandle)

	//========================表单提交方法======================
	// 绑定路由规则
	r.POST("/user/search", formParamsHandle)

	//json
	// 绑定路由规则
	r.POST("/user/json", paramsJsonHandle)

	//

	// 绑定路由规则--文件上传
	r.POST("/upload/single", singleFileUploadHandle)

	 绑定路由规则--多文件上传
	r.POST("/upload/multi", multiFileUploadHandle)
	// 监听端口
	r.Run(":9000")
}

2.5参数绑定--优化数据方式
使用 ShouldBind() 方法, 根据请求方式,自动提取 JSON, form表单 和 Query 类型的参数,放入结构体中

2.5.1url query参数解析

 

 

2.5.2form表单参数解析

 

2.5.3json 数据解析

 

三、程序的所有代码

package main

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
)

// /user/search?username=zhangsan&address=北京
// urlQuery 获取 url中?后面携带的参数
func urlQueryHandle(ctx *gin.Context) {
	// 如果指定的key 没有对应的值就使用默认值
	username1 := ctx.DefaultQuery("username", "lisi")

	// 根据key 获取值
	username2 := ctx.Query("username")

	address := ctx.Query("address")

	// 返回JSON 字符串
	ctx.JSON(http.StatusOK, gin.H{
		"message":   "ok",
		"username1": username1,
		"username2": username2,
		"address":   address,
	})
}

// /user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
// paramsPathHandle 获取url path中参数
func paramsPathHandle(ctx *gin.Context) {

	// 获取参数值
	username := ctx.Param("username")
	address := ctx.Param("address")

	// 数据返回
	ctx.JSON(http.StatusOK, gin.H{
		"message":  "ok",
		"username": username,
		"address":  address,
	})
}

//=================================

// formParamsHandle 获取form表单提交数据
func formParamsHandle(ctx *gin.Context) {

	// 获取不到值时就是用默认值
	username1 := ctx.DefaultPostForm("username", "lisi")

	username2 := ctx.PostForm("username")
	address := ctx.PostForm("address")

	// 以Json 字符串的形式返回
	ctx.JSON(http.StatusOK, gin.H{
		"message":   "ok",
		"username1": username1,
		"username2": username2,
		"address":   address,
	})
}

// json参数
// paramsJsonHandle 获取json字符串相关的参数
func paramsJsonHandle(ctx *gin.Context) {

	// 获取request.Body() 中的数据(这里没有进行错误处理)
	// 返回的是字节数组
	dataBytes, _ := ctx.GetRawData()

	// 定义一个map
	var m map[string]interface{}

	// 反序列化 别忘了&
	_ = json.Unmarshal(dataBytes, &m)

	// 数据返回
	ctx.JSON(http.StatusOK, m)

}

//文件上传
/*
  单个文件上传
    文件上传接收的文件格式是: multipart/form-data
*/

// singleFileUploadHandle 当文件上传
func singleFileUploadHandle(ctx *gin.Context) {

	// 获取文件
	// 根据上传时的参数名获取上传的文件内容 --> 返回对象为 *multipart.FileHeader
	fileHeader, err := ctx.FormFile("file")
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"message": err.Error(),
		})
		return
	}

	// 保存文件内容
	// 拼接文件名, 这里直接写死了
	targetFileName := fmt.Sprintf("C:/Users/黑熊精/Pictures/%s", fileHeader.Filename)
	//targetFileName := fmt.Sprintf("%s", fileHeader.Filename)

	// 将文件保存到指定的目录
	err = ctx.SaveUploadedFile(fileHeader, targetFileName)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"message": err.Error(),
		})
	} else {
		ctx.JSON(http.StatusOK, gin.H{
			"message": fmt.Sprintf("%s upload success!", fileHeader.Filename),
		})
	}
}

//多文件上传

/**
  多文件上传
*/

// multiFileUploadHandle 多文件上传
func multiFileUploadHandle(ctx *gin.Context) {

	// form 是一个存储文件信息的结构体
	/**
	  type Form struct {
		Value map[string][]string
		File  map[string][]*FileHeader
	*/
	form, err := ctx.MultipartForm()
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"message": err.Error(),
		})
		return
	}

	// 获取文件列表,并保存, 返回的是一个切片 []*FileHeader
	files := form.File["file"]
	for i, file := range files {
		targetFileName := fmt.Sprintf("C:/Users/黑熊精/Pictures/%d_%s", i, file.Filename)
		err = ctx.SaveUploadedFile(file, targetFileName)

		if err != nil {
			ctx.JSON(http.StatusInternalServerError, gin.H{
				"message": err.Error(),
			})
			return
		}
	}
	ctx.JSON(http.StatusOK, gin.H{
		"message": fmt.Sprintf("upload success!"),
	})
}

// shuldbind数据的绑定的办法
// 使用 ShouldBind() 方法, 根据请求方式,自动提取 JSON, form表单 和 Query 类型的参数,放入结构体中
// 用户信息信息结构体
// 加上 binding:"required" 标签,说明该参数是必填的,如果不填就会报错
type UserInfo struct {
	Username string `json:"username" form:"username" binding:"required"`
	Address  string `json:"address" form:"address" binding:"required"`
}

// 获取query参数
func queryHandle(ctx *gin.Context) {
	var userInfo UserInfo

	// 获取数据
	err := ctx.ShouldBind(&userInfo)
	if err == nil {
		ctx.JSON(http.StatusOK, gin.H{
			"message":  "ok",
			"username": userInfo.Username,
			"address":  userInfo.Address,
		})
	} else {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
	}
}

func jsonHandle(ctx *gin.Context) {
	var userInfo UserInfo

	// 获取数据
	err := ctx.ShouldBind(&userInfo)
	if err == nil {
		ctx.JSON(http.StatusOK, gin.H{
			"message":  "ok",
			"username": userInfo.Username,
			"address":  userInfo.Address,
		})
	} else {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
	}
}

func fromHandle(ctx *gin.Context) {
	var userInfo UserInfo

	// 获取数据
	err := ctx.ShouldBind(&userInfo)
	if err == nil {
		ctx.JSON(http.StatusOK, gin.H{
			"message":  "ok",
			"username": userInfo.Username,
			"address":  userInfo.Address,
		})
	} else {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
	}
}

func main() {

	// 创建默认路由
	r := gin.Default()
	//两种浏览器地址获取参数的办法
	// 绑定路由规则 /user/search?username=zhangsan&address=北京
	r.GET("/user/search", urlQueryHandle)
	// 2. 绑定路由规则/user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
	r.GET("/user/search/:username/:address", paramsPathHandle)

	//========================表单提交方法======================
	// 绑定路由规则
	r.POST("/user/search", formParamsHandle)

	//json
	// 绑定路由规则
	r.POST("/user/json", paramsJsonHandle)

	//

	// 绑定路由规则--文件上传
	r.POST("/upload/single", singleFileUploadHandle)

	 绑定路由规则--多文件上传
	r.POST("/upload/multi", multiFileUploadHandle)

	//使用 ShouldBind() 方法, 根据请求方式,自动提取 JSON, form表单 和 Query 类型的参数,放入结构体中
	// 绑定路由规则
	r.GET("/user/query", queryHandle)
	r.POST("/user/form", fromHandle)
	r.POST("/user/jsons", jsonHandle)
	// 监听端口
	r.Run(":9000")
}

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

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

相关文章

【业务功能篇58】Springboot + Spring Security 权限管理 【中篇】

4.2.3 认证 4.2.3.1 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打卡,当你的指纹和系统里录入的指纹相匹配时&…

图注意力网络论文详解和PyTorch实现

图神经网络(gnn)是一类功能强大的神经网络,它对图结构数据进行操作。它们通过从节点的局部邻域聚合信息来学习节点表示(嵌入)。这个概念在图表示学习文献中被称为“消息传递”。 消息(嵌入)通过多个GNN层在图中的节点之间传递。每个节点聚合来自其邻居的消息以更新其…

【小白必看】Python爬虫实战之批量下载女神图片并保存到本地

文章目录 前言运行结果部分图片1. 引入所需库2. 发送请求获取网页内容3. 解析网页内容并提取图片地址和名称4. 下载并保存图片完整代码关键代码讲解 结束语 前言 爬取网络上的图片是一种常见的需求,它可以帮助我们批量下载大量图片并进行后续处理。本文将介绍如何使…

django学习笔记(1)

django创建项目 先创建一个文件夹用来放django的项目,我这里是My_Django_it 之后打开到该文件下,并用下面的指令来创建myDjango1项目 D:\>cd My_Django_itD:\My_Django_it>"D:\zzu_it\Django_learn\Scripts\django-admin.exe" startpr…

echarts遇到的问题

文章目录 折线图-区域面积图 areaStyley轴只有整数y轴不从0开始y轴数值不确定,有大有小,需要动态处理折线-显示label标线legend的格式化和默认选中状态x轴的lable超长处理x轴的相关设置 echarts各个场景遇到的问题 折线图-区域面积图 areaStyle areaStyl…

分库分表之基于Shardingjdbc+docker+mysql主从架构实现读写分离(二)

说明:如果实现了docker部署mysql并完成主从复制的话再继续,本篇文章主要说明springboot配置实现Shardingjdbc进行读写分离操作。 如果没实现docker部署mysql实现主从架构的话点击我 Shardingjdbc配置介绍(版本:5.3.2)…

STM32 Flash学习(一)

STM32 FLASH简介 不同型号的STM32,其Flash容量也不同。 MiniSTM32开发板选择的STM32F103RCT6的FLASH容量为256K字节,属于大容量产品。 STM32的闪存模块由:主存储器、信息块和闪存存储器接口寄存器等3部分组成。 主存储器,该部分…

linux 指令 第3期

cat cat 指令: 首先我们知道一个文件内容属性 我们对文件操作就有两个方面:对文件内容和属性的操作 扩展:echo 指令 直接打印echo后面跟的字符串 看: 这其实是把它打印到了显示器上,我们也可以改变一下它的打印位置…

工业边缘计算为什么?

在工厂环境中使用边缘计算并不新鲜。可编程逻辑控制器(PLC)、微控制器、服务器和PC进行本地数据处理,甚至是微型数据中心都是边缘技术,已经在工厂系统中存在了几十年。在车间里看到的看板系统,打卡系统,历史…

加解密相关工具网站总结

加解密相关工具&网站总结 文章目录 加解密相关工具&网站总结CMD5,解密,反向查询JSFuck(JavaScriptAAEncode加密/解密(Javascript在线CTF编码工具开源加解密工具大佬文章:1.30余种加密编码类型的密文特征分析2.…

手把手一起上传本地项目至Gitee仓库

1、Gitee新建仓库 创建自己的Gitee账号,新建仓库,如图所示: 根据自己的项目情况,填写仓库信息,如图所示: 仓库创建完成,如图所示: 2、下载Git 下载地址可用链接: https://registry…

陕西师范大学大学:融合传统与创新的学府之旅

前言 > 📕作者简介:热爱跑步的恒川,致力于C/C、Java、Python等多编程语言,热爱跑步,喜爱音乐的一位博主。 > 📗本文收录于恒川的日常汇报系列,大家有兴趣的可以看一看 > &#x1f4d…

Knowledge-QA-LLM: 基于本地知识库+LLM的开源问答系统

⚠️注意:后续更新,请移步README Knowledge QA LLM 基于本地知识库LLM的问答系统。该项目的思路是由langchain-ChatGLM启发而来。缘由: 之前使用过这个项目,感觉不是太灵活,部署不太友好。借鉴如何用大语言模型构建一…

2023年深圳杯数学建模D题基于机理的致伤工具推断

2023年深圳杯数学建模 D题 基于机理的致伤工具推断 原题再现: 致伤工具的推断一直是法医工作中的热点和难点。由于作用位置、作用方式的不同,相同的致伤工具在人体组织上会形成不同的损伤形态,不同的致伤工具也可能形成相同的损伤形态。致伤…

elementui el-table 封装表格

ps: 1.3版本 案例&#xff1a; 完整代码&#xff1a; 可直接复制粘贴&#xff0c;但一定要全看完&#xff01; v-slot"scopeRows" 是vue3的写法&#xff1b; vue2是 slot-scope"scope" <template><!-- 简单表格、多层表头、页码、没有合并列行…

iOS 应用上架的步骤和工具简介

编辑 APP开发助手是一款能够辅助iOS APP上架到App Store的工具&#xff0c;它解决了iOS APP上架流程繁琐且耗时的问题&#xff0c;帮助跨平台APP开发者顺利将应用上架到苹果应用商店。最重要的是&#xff0c;即使没有配置Mac苹果机&#xff0c;也可以使用该工具完成一系列操作&…

Merge the squares! 2023牛客暑期多校训练营4-H

登录—专业IT笔试面试备考平台_牛客网 题目大意&#xff1a;有n*n个边长为1的小正方形摆放在边长为n的大正方形中&#xff0c;每次可以选择不超过50个正方形&#xff0c;将其合并为一个更大的正方形&#xff0c;求一种可行的操作使所有小正方形都被合并成一个n*n的大正方形 1…

找不到mfc140u.dll怎么解决

第一&#xff1a;mfc140u.dll有什么用途&#xff1f; mfc140u.dll是Windows操作系统中的一个动态链接库文件&#xff0c;它是Microsoft Foundation Class (MFC)库的一部分。MFC是 C中的一个框架&#xff0c;用于构建Windows应用程序的用户界面和功能。mfc140u.dll包含了MFC库中…

“RWEQ+”集成技术在土壤风蚀模拟与风蚀模数估算、变化归因分析中的实践

土壤风蚀是一个全球性的环境问题。中国是世界上受土壤风蚀危害最严重的国家之一&#xff0c;土壤风蚀是中国干旱、半干旱及部分湿润地区土地荒漠化的首要过程。中国风蚀荒漠化面积达160.74104km2&#xff0c;占国土总面积的16.7%&#xff0c;严重影响这些地区的资源开发和社会经…

GitLab开启双端认证并登录GitLab

GitLab开启双端认证并登录GitLab 1.介绍双端认证 单重认证——密码验证&#xff0c;这极其容易出现密码被盗&#xff0c;密码泄露等危险事件。 于是为了提高安全性&#xff0c;就出现了双因素认证&#xff0c;多因素认证。登录的时候不仅要输入账号和密码还需要输入一个验证码…