加载中...

Golang Gin 获取Restful参数、URL查询参数,Form 表单参数,JSON格式参数

前言

http请求中, 可以通过URL查询参数提交数据到服务器,可以通过post的json方式,还有一直方式就是Form表单。Form表单相比URL查询参数,用户体验好,可以承载更多的数据,尤其是文件上传时,特别方便。

这里推荐 飞雪无情的博客;写了一些列的gin的使用教程,很时候新手学习
如果想对gin有一个完整的了解,也可以查看这个 Gin框架中文文档;文档相对比较完整一些

正文

Gin获取Restful路由参数

Gin实现路由参数非常简单:

func main() {
	r := gin.Default()

	r.GET("/users/:id", func(c *gin.Context) {
		id := c.Param("id")
		c.String(200, "The user id is  %s", id)
	})
	r.Run(":8080")
}

Gin的路由采用的是httprouter开源库,所以它的路由参数的定义和httprouter也是一样的。

冒号匹配(😃

/users/:id 就是一种路由匹配模式,也是一个通配符,其中:id就是一个路由参数

我们可以通过c.Param("id")获取定义的路由参数的值。

/users/:id这种匹配模式是精确匹配的,只能匹配一个;例如:

Pattern: /users/:id

/users/123          匹配
/users/哈哈        匹配
/users/123/go      不匹配
/users/             不匹配

星号路由参数(*)

上面我们介绍的是:号的路由参数,这种路由参数最常用。还有一种不常用的就是*号类型的参数,表示匹配所有。

/users/*id为例:

我们可以通过c.Param("id")获取定义的路由参数的值。

Pattern: /users/*id

/users/123         匹配
/users/哈哈        匹配
/users/123/go      匹配
/users/            匹配

URL查询参数(query parames)

URL查询参数简称为URL参数,是存在于我们请求的URL中,以?为起点,后面的k=v&k1=v1&k2=v2这样的字符串就是查询参数,例如:

http://127.0.0.1:8080/users?name=zzx&age=18

获取URL查询参数的方法有多个,我们分别介绍一下,案例:

func main() {
	r := gin.Default()

	r.GET("/", func(c *gin.Context) {
        // Query 就是最常用的一个方法
		c.String(200, c.Query("wechat"))
	})
	r.Run(":8080")
}
/** 方便整理,查询方法都放到这里 */

// 获取 name 对应的值。如果为空,则返回空字符串;
value := c.Query("name")

// 获取 name 对应的值,和是否存在 name参数的,ok是 bool 类型
value, ok := c.GetQuery("name")


// 当url中的参数是多选传递时,则需要获取为数组;
// 例如 ?name="张三"&name="Zach" 
// 相同的key对应了不同的value,则需要使用这种方式
arr := c.QueryArray("name")

// 作用和 QueryArray 相同,只是多了一个是否有指定key的 返回
arr, ok := c.GetQueryArray("name")

// 当我们按Gin要求的 map 格式传递参数时,则需要获取为map
// 例如 ?ids[a]=1&ids[b]=2&ids[c]=3
// 从以上URL看,关键在于key,这个key必须符合map的定义,[]外面的必须相同,也就是ids这个map变量名,
// []里面的,也就是map的key不能相同,
// 这样就满足了Gin定义的把URL查询参数转换为map的格式定义。
myMap := c.QueryMap("ids")

// 作用和 QueryMap 相同,只是多了一个判断,是否存在对应的key
myMap, ok := c.GetQueryMap("ids")

// 带默认值的获取,如果不存在,则用默认值填充
defaultValue := c. DefaultQuery("name","李四")

获取Form表单参数

通过URL查询参数提交数据到服务器外,常用的还有通过Form表单的方式。Form表单相比URL查询参数,用户体验好,可以承载更多的数据,尤其是文件上传,更是简单。

对于Form表单来说,有两种提交方式GET和POST。其中GET方式就是上面提到的URL查询参数的方式,参考即可获得对应的参数键值对,下面主要介绍POST的方式的表单,而Gin处理的也是这种表单。

Gin 对于表单数据的获取也非常简单,为我们提供了和获取URL查询参数一样的系列方法。

这里需要注意的是保存表单缓存的内存大小,Gin默认给的是32M 如果你觉得不够,可以提前通过修改MaxMultipartMemory的值增加,比如:
r := gin.Default()
r.MaxMultipartMemory = 100 << 20

func main() {
	r := gin.Default()
	r.POST("/", func(c *gin.Context) {
		name := c.PostForm("name")
		c.String(200, name)
	})

	r.Run(":8080")
}

方便整理,查询方法都放到这里

// 获取 key为 name的表单值
value := c.PostForm("name")

// 获取 key为 name的表单值,多了一个ok,确定是否存在对应的key
value, ok := c.GetPostForm("name")

arr := c.PostFormArray("name")
arr, ok := c.GetPostFormArray("name")

myMap := c.PostFormMap("ids")
myMap, ok := c.GetPostFormMap("ids")

defaultValue := c. DefaultPostForm("name","李四")

Url参数获取和Form表单参数获取对比

查询参数 Form表单 说明
Query PostForm 获取key对应的值,不存在为空字符串
GetQuery GetPostForm 多返回一个key是否存在的结果
QueryArray PostFormArray 获取key对应的数组,不存在返回一个空数组
GetQueryArray GetPostFormArray 多返回一个key是否存在的结果
QueryMap PostFormMap 获取key对应的map,不存在返回空map
GetQueryMap GetPostFormMap 多返回一个key是否存在的结果
DefaultQuery DefaultPostForm key不存在的话,可以指定返回的默认值

获取Content-Type: application/json请求头的JSON数据

通过Content-Type: application/json 请求头发送json格式的数据算是最常用了,Gin解析这种方式上传的数据非常方便,一般有两种方法

主要使用 c.BindJSON 方法;查看源码中,还可以解析XML等多种格式。最后都是调用了 c.Bind() 函数

方法一:解析到Map 中

func Login(c *gin.Context) {
	json := make(map[string]interface{}) //注意该结构接受的内容
	c.BindJSON(&json)
	log.Printf("%v",&json)
	c.JSON(http.StatusOK, gin.H{
		"name": json["name"],
		"password": json["password"],
	})
}

方法二:直接解析到对应的 struct 对象中

type User struct {
	Name string `json:"name"`
	Password int64 `json:"password"`
}
func Login(c *gin.Context) {
	json := User{}

	c.BindJSON(&json)

	log.Printf("%v",&json)
	c.JSON(http.StatusOK, gin.H{
		"name": json.Name,
		"password": json.Password,

	})
}

获取上传文件

获取上传文件,主要有两个方法, c.FormFile(key)c.MultipartForm() 和一个存储文件函数c.SaveUploadedFile(file,path)

单文件上传:c.FormFile(key)

func main() {
    router := gin.Default()
    // 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
    // router.MaxMultipartMemory = 8 << 20  // 8 MiB
    router.POST("/upload", func(c *gin.Context) {
        // 单文件
        file, _ := c.FormFile("file")
        log.Println(file.Filename)

        // 上传文件至指定目录
        // c.SaveUploadedFile(file, dst)

        c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
    })
    router.Run(":8080")
}

多文件上传

func main() {
    router := gin.Default()
    // 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
    // router.MaxMultipartMemory = 8 << 20  // 8 MiB
    router.POST("/upload", func(c *gin.Context) {
        // Multipart form
        form, _ := c.MultipartForm()
        files := form.File["upload[]"]

        for _, file := range files {
            log.Println(file.Filename)

            // 上传文件至指定目录
            // c.SaveUploadedFile(file, dst)
        }
        c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
    })
    router.Run(":8080")
}
posted @ 2023-11-06 11:16  水车  阅读(810)  评论(0编辑  收藏  举报