gin 二.请求数据获取基础

gin中的路由

  • 一. gin.Context.Params URL路径参数获取
  • 二. URL 传参获取
  • 三. 表单参数
  • 四. 文件上传
  • 五. 接收请求头
    • 使用c.Request.Header方法
    • 使用c.GetHeader方法

一. gin.Context.Params URL路径参数获取

  1. 在gin中所有跟请求相关的数据都包装在了gin.Context结构中(这里先简单看一下Context,后面有专门文档讲解)
// Context是gin最重要的部分。它允许我们在中间件之间传递变量,
// 管理流程,验证请求的JSON并渲染JSON响应等。
type Context struct {
	//响应处理(实现了http.ResponseWriter 和 gin.ResponseWriter)
	writermem responseWriter
	// Request是一个指向http.Request类型的指针,表示当前的HTTP请求
	Request   *http.Request 
	// Writer是一个ResponseWriter类型的接口,表示当前的HTTP响应
	Writer    ResponseWriter 
	// Params是一个Params类型的切片,表示URL中的参数
	Params   Params 
	// handlers是一个HandlersChain类型的切片,表示注册的中间件和处理函数
	handlers HandlersChain 
	// index是一个int8类型的变量,表示当前执行到第几个中间件或处理函数
	index    int8 
	// fullPath是一个string类型的变量,表示当前请求的完整路径
	fullPath string 
	// engine是一个指向Engine类型的指针,表示当前使用的Gin引擎
	engine   *Engine 
	// params是一个指向Params类型的指针,表示URL中的参数(与Params字段相同)
	params   *Params 
	// skippedNodes是一个指向skippedNode类型切片的指针,表示跳过的路由节点
	skippedNodes *[]skippedNode 
	// mu是一个sync.RWMutex类型的变量,用于保护Keys字段
	mu sync.RWMutex 
	// Keys是一个键值对映射,专门用于每个请求的上下文。
	Keys map[string]interface{}

	// Errors是一个错误列表,附加到所有使用这个上下文的处理器/中间件。
	Errors errorMsgs

	// Accepted定义了一个手动接受的格式列表,用于内容协商。
	Accepted []string

	// queryCache是一个url.Values类型的变量,缓存了c.Request.URL.Query()的结果。
	queryCache url.Values 

	// formCache是一个url.Values类型的变量,缓存了c.Request.PostForm,它包含了从POST, PATCH或PUT请求体中解析出来的表单数据。
	formCache url.Values 

	// sameSite是一个http.SameSite类型的变量,允许服务器定义一个cookie属性,使得浏览器不能在跨站请求中发送这个cookie。
	sameSite http.SameSite 
}
  1. gin.Context,内部有一个Params字段,该字段是一个Param结构的切片,内部保存了url参数,并且Context中还提供了一个Param(“key”)方法,可以根据指定key获取对应的value
//gin.Context 下
//Params 字段,表示URL中的参数
type Params []Param

//Context绑定的Param方法,会根据key值获取Params中的指定Param
func (c *Context) Param(key string) string {
	return c.Params.ByName(key)
}

//Param
type Param struct {
	Key   string
	Value string
}
  1. 示例:
  1. 注册路由时,url路径上使用"/:路径key"指定路径key
  2. 在处理器接口中获取到Context下的Params属性,根据该属性获取指定值
package moduleRoute

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

func CreateRouter() *gin.Engine {
	//获取默认RouterRouter
	router := gin.Default()

	//注意点1:在编写请求路径是,url参数中,代表key值的url前要加":"
	router.GET("/getUrl/:year/:day", GetUrlFunc)

	return router
}

func GetUrlFunc(c *gin.Context) {
	//注意点2,在使用Param接收url参数时,获取出来的数据类型都是string
	//后续使用时,要注意进行类型转换

	//1.通过Context下的Params字段可以获取到存有所有url参数的切片
	var params gin.Params = c.Params
	for _, item := range params {
		fmt.Println(item.Key)
		fmt.Println(item.Value)
	}

	//2.通过Context调用绑定的Param方法,传入key值获取指定的val
	year := c.Param("year")
	day := c.Param("day")
	str := fmt.Sprintf("year:%v day:%v", year, day)
	c.String(http.StatusOK, str)
}

二. URL 传参获取

  1. 例如发送请求":8080/getUrl?key1=数据1&key2=数据2",获取key1,key2的值
router.GET("/getUrlKey", GetUrlKey)

func GetUrlKey(c *gin.Context) {
	
	//name := c.Query("name") 
	c.Request.URL.Query().Get("name")
	
	//1.通过调用DefaultQuery()给指定key设置默认值
	//如果下方实际获取的值为空,则使用此处设置的值
	name:= c.DefaultQuery("name", "默认值")
	c.String(http.StatusOK, fmt.Sprintf("name %s", name))
}

三. 表单参数

  1. http的报⽂体传输数据就⽐query string稍微复杂⼀点,常⻅的格式就有四种,application/json , application/x-www-form-urlencoded , application/xml 和multipart/form-data 。后⾯⼀个主要⽤于图⽚上传。json格式的很好理解,urlencode其实也不难,⽆⾮就是把query string的内容,放到了body体⾥,同样也需要urlencode。默认情况下,c.PostFROM解析的是 x-www-form-urlencoded 或 from-data 的参数
  2. 接收请求接口
router.POST("/postFormVal", FormFunc)

func FormFunc(c *gin.Context) {
	//1.通过PostForm()获取表单中指定key的值
	username := c.PostForm("username")
	password := c.PostForm("password")
	//2.可设置默认值
	type1 := c.DefaultPostForm("type", "alert")

	//3.假设传递过来的是数组,或map多个参数时使用
	//PostFormMap() 方法或 QueryArray
	//或: PostFormArray()
	//hobbys := c.PostFormMap("hobby")
	//hobbys := c.QueryArray("hobby")
	hobbys := c.PostFormArray("hobby")
	c.String(http.StatusOK, fmt.Sprintf("type is %s, username is %s,passwordis % s, hobbyis % v", type1, username, password, hobbys))
}

四. 文件上传

  1. multipart/form-data 转⽤于⽂件上传。gin⽂件上传也很⽅便,和原⽣的net/http⽅法类似,不同是gin把原⽣的request封装到c.Request中
  2. 单个文件上传示例
func multipartFunc(c *gin.Context) {

	//1.调用FormFile("file")获取文件数据"file"是固定的
	file, _ := c.FormFile("file")
	log.Println(file.Filename)

	// 2.调用SaveUploadedFile将文件上传到指定目录
	//Upload the file to specific dst.(此处是上层到当前项目下)
	c.SaveUploadedFile(file, file.Filename)
	
	// 也可以直接使⽤io操作,拷⻉⽂件数据。
	//c.SaveUploadedFile()底层也是封装的这块代码
	//out, err := os.Create(filename)
	//defer out.Close()
	// _, err = io.Copy(out, file)
	

	c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
}
  1. 注意点: 使⽤ c.Request.FormFile 解析客户端⽂件name属性。如果不传⽂件,则会抛错,因此需要处理这个错误。此处我们略写了错误处理。⼀种是直接⽤c.SaveUploadedFile()保存⽂件。另⼀种⽅式是使⽤os的操作,把⽂件数据复制到硬盘上
  2. 上传多个文件(与单个文件不同是一次拿到多个,然后遍历上传)
func MultipartFuncs(c *gin.Context) {
	//1.读取文件数据此方式会读取到调用方传递的整个form
	form, err := c.MultipartForm()
	if err != nil {
		c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error()))
		return
	}
	//2.获取form中的所有文件
	files := form.File["files"]
	
	//3.遍历拿到的文件
	for _, file := range files {
		//4.上传文件
		if err := c.SaveUploadedFile(file, file.Filename); err != nil {
			c.String(http.StatusBadRequest, fmt.Sprintf("upload file err:%s", err.Error()))
			return
		}
	}
	c.String(http.StatusOK, fmt.Sprintf("Uploaded successfully %d files ",
		len(files)))
}

五. 接收请求头

  1. 有以下三种方式获取请求头
  1. c.Request.Header
  2. c.GetHeader
  3. c.ShouldBindHeader使用绑定器

使用c.Request.Header方法

  1. c.Request.Header方法是一种获取请求头的方式,它可以返回一个map[string][]string类型的对象,包含了所有的请求头键值对。我们可以通过指定请求头的名称,获取对应的值
func main() {
	r := gin.Default() // 创建一个默认的gin引擎

	// 注册一个GET路由
	r.GET("/auth", func(c *gin.Context) {
		// 获取请求头中的Token值,如果有多个值,只取第一个
		token := c.Request.Header["Token"][0]
		// 判断Token是否有效
		if token == "secret" {
			// Token有效,返回200状态码和"authorized"字符串
			c.String(200, "authorized")
		} else {
			// Token无效,返回401状态码和"unauthorized"字符串
			c.String(401, "unauthorized")
		}
	})

	r.Run(":8080") // 启动服务器
}

使用c.GetHeader方法

  1. c.GetHeader方法是另一种获取请求头的方式,它可以直接返回一个字符串类型的值,表示指定的请求头的值。如果请求头不存在或为空,它会返回一个空字符串。
func main() {
	r := gin.Default() // 创建一个默认的gin引擎

	// 注册一个GET路由
	r.GET("/auth", func(c *gin.Context) {
		// 获取请求头中的Token值
		token := c.GetHeader("Token")
		// 判断Token是否有效
		if token == "secret" {
			// Token有效,返回200状态码和"authorized"字符串
			c.String(200, "authorized")
		} else {
			// Token无效,返回401状态码和"unauthorized"字符串
			c.String(401, "unauthorized")
		}
	})

	r.Run(":8080") // 启动服务器
}

你可能感兴趣的:(#,十二.,gin,底层原理与基本使用,gin,服务器,java)