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

news2024/11/15 17:49:56

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")
}

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

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

相关文章

linux的一些基本指令第二期

rm rm -r 你要删除的目录名 加了-r 之后表示递归删除你要删除的目录 使用这个命名之后,他会一边递归到叶子节点,一边询问你是否要删除,然后会递归回来,在回来的途中删除: rm -rf 你要删除的目录名 强制执行删除操作…

权威认证!伙伴云入选亿欧2023AIGC应用场景创新TOP50榜单

近日, 知名科技与产业创新服务平台【亿欧】发布2023年度AIGC应用场景创新TOP50榜单。 伙伴云作为行业领先的零代码应用搭建平台,率先推出AI智能搭建系统功能,并将Chat GPT应用嵌入伙伴云应用在解决方案层,最终凭借前沿的技术创新力和突出的数…

【NVMe2.0d 17 - 1】Reservation 核心命令

文章目录 Reservation RegisterReservation AcquireReservation ReportReservation Release Reservation Register Reservation Register命令用于注册、取消注册或替换reservation key。 该命令使用Command Dword 10和内存中的Reservation Register data structure 如果该命…

基于seaborn.countplot的柱状图显示Y值及填充形状

参考链接: seaborn 柱状图上显示y值的方法 python柱形图填充 figs,ax plt.subplots(figsize(10,4)) fig sns.countplot(x"状态",hue"等级", datadatas)// 不可通过设置hatch参数来设置 marks ["o","---","***&quo…

IDEA批量启动多个微服务

注:现在盛行微服务开发,通常需要通过idea启动多个项目,每次都一个一个的启动,太麻烦了,不过被担心idea帮我们考虑到这个了(不用安装插件哦) 配置步骤: 将需要一次性全部启动的微服务…

[STL]详解vector模拟实现

[STL]vector模拟实现 文章目录 [STL]vector模拟实现1. 整体结构总览2. 成员变量解析3. 默认成员函数构造函数1构造函数2构造函数3拷贝构造函数析构函数 4. 迭代器相关函数begin函数end函数begin函数const版本end函数const版本 5.容量相关函数size函数capacity函数reserve函数re…

【Nodejs】操作mongodb数据库

1.简介 Mongoose是一个让我们可以通过Node来操作MongoDB的模块。Mongoose是一个对象文档模型(ODM)库,它对Node原生的MongoDB模块进行了进一步的优化封装,并提供了更多的功能。在大多数情况下,它被用来把结构化的模式应用到一个MongoDB集合,并…

【每日一题】2500. 删除每行中的最大值

【每日一题】2500. 删除每行中的最大值 2500. 删除每行中的最大值题目描述解题思路 2500. 删除每行中的最大值 题目描述 给你一个 m x n 大小的矩阵 grid ,由若干正整数组成。 执行下述操作,直到 grid 变为空矩阵: 从每一行删除值最大的元…

阿里Java开发手册~建表规约

1. 【强制】表达是与否概念的字段,必须使用 is _ xxx 的方式命名,数据类型是 unsigned tinyint ( 1 表示是, 0 表示否 ) 。 说明: 任何字段如果为非负数,必须是 unsigned 。 正例&am…

Jenkins+Docker+Docker-Compose自动部署,SpringCloud架构公共包一个任务配置

前言 Jenkins和docker的安装,随便百度吧,实际场景中我们很多微服务的架构,都是有公共包,肯定是希望一个任务能够把公共包的配置加进去,一并构建,ok,直接上干货。 Jenkins 全局环境安装 pwd e…

建造者模式——复杂对象的组装与创建

1、简介 1.1、概述 建造者模式又称为生成器模式,它是一种较为复杂、使用频率也相对较低的创建型模式。建造者模式向客户端返回的不是一个简单的产品,而是一个由多个部件组成的复杂产品。 建造者模式是较为复杂的创建型模式,它将客户端与包…

【chatGpt】关于websocket连接中对未授权的捕捉问题

目录 问题 有效提问 有效的细节提问 问题 一路上,通过简单的error进行判断弹出授权,会有很多乱弹的现象: (1)链路正常切换会断 (2)服务器没有启动会连接不上 (3)没…

Pytorch深度学习-----DataLoader的用法

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用(ToTensor,Normalize,Resize ,Co…

【Golang】基于OAuth2.0微信扫码实现客户端用户登录(原理+代码实现+视频讲解)

前言: 细心汇总,包括原理+配置+代码详细实现 文章目录 原理讲解什么是OAuth2.0解决方案授权码模式讲解认证流程Go语言实现微信扫码登录1. 内网穿透配置2. 微信测试账号申请3. 验证和微信服务器连接二维码生成回调地址测试原理讲解 什么是OAuth2.0 OAuth 2.0是一种授权协议,…

JavaScript学习 --消息摘要算法

消息摘要算法(也称哈希算法)是一种将任意大小的数据转换为一个固定大小的数据序列的算法。在JavaScript中,常见的消息摘要算法包括MD5、SHA-1、SHA-256等。它们适用于安全传输敏感数据、防篡改数据等场景。在本篇博客中,我们将介绍…

slurm/sbatch/srun 多步骤串行运行多个依赖性任务

在slurm系统下,有时候需要按步骤运行A、B、C三个任务,但是直接写在脚本里会同时提交,所以需要建立依赖关系。 错误做法: 搜索网上做法及slurm串行教程,做法多为如下,使用bash或python来按顺序/循环内来串…

顺序表详解

💓博主个人主页:不是笨小孩👀 ⏩专栏分类:数据结构与算法👀 🚚代码仓库:笨小孩的代码库👀 ⏩社区:不是笨小孩👀 🌹欢迎大家三连关注,一起学习,一起进步&#…

NetApp FAS2750 和 FAS2820:适用于分布式企业和从远程到核心的 FAS

NetApp FAS2750 和 FAS2820:适用于分布式企业和从远程到核心的 FAS 拥有分布式企业和多个办公位置的客户希望使用这些系统进行虚拟化,以及为大型 FAS 和 AFF 系统提供简单且经济高效的备份和灾难恢复。 为什么要从 NetApp FAS 系列中选择一个型号&…

LLM / Python - json 使用详解

目录 一.引言 二.json 方法 1.json.dumps 2.json.dump 3.json.loads 4.json.load 三.json 参数 1.ensure_ascii 2.allow_nan 3.indent 4.sortKeys 5.Other 四.LLM 数据构建 1.json 数据构建 2.Train.py 五.总结 一.引言 上文中我们介绍了 LLama2-Chinese 的简…

ipad手写笔有必要买原装吗?质量好苹果平板平替笔推荐

因为iPad平板的强大,使得很多人群都用上了iPad,而且还在不断的普及。不管是用于绘画或者学习记笔记,都非常好用,但要是用来看电视剧玩游戏就没那么有价值了。如果你不打算购买昂贵的苹果电容笔,或者只是为了记录&#…