Golang Gin 实战(六)| 获取Form表单参数和原理分析

2,048 阅读5分钟
原文链接: mp.weixin.qq.com

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

Form 表单

对于Form表单,我们不会陌生,比如input文本框、密码框等等,可以让我们输入 一些数据,然后点击「保存」、「提交」等按钮,把数据提交到服务器的。

对于Form表单来说,有两种提交方式GETPOST。其中GET方式就是我们前两篇文章的URL查询参数的方式,参考即可获得对应的参数键值对,这篇文章主要介绍 POST的方式的表单,而Gin处理的也是这种表单。

Gin 接收表单数据

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

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

运行这段代码,然后打开终端输入curl -d wechat=flysnow_org http://localhost:8080/ 回车,就会看到打印的如下信息:

flysnow_org

这里我们通过curl这个工具来模拟POST请求,当然你可以可以使用 Postman比较容易操作的可视化工具。

在这个Gin示例中,使用 PostForm方法来获取相应的键值对,它接收一个key,也就是我们 htmlinput这类表单标签的 name属性值。

PostForm方法和查询参数的 Query是一样的,如果对应的key不存在则返回空字符串。

Gin PostForm系列方法

和查询参数方法一样,对于表单的参数接收,Gin也提供了一系列的方法,他们的用法和查询参数的一样。

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

通过这个表格以及对应和说明,可以更好记一些。

实现原理

关于PostForm系列方法的实现原理和 Query系列类似,并且遵循Query-GetQuery-GetQueryArray这么一个内部调用顺序,所以我们直接看 GetPostFormArray的源代码即可。

func (c *Context) GetPostFormArray(key string) ([]string, bool) {    c.getFormCache()    if values := c.formCache[key]; len(values) > 0 {        return values, true    }    return []string{}, false}

这里关键点在于getFormCache缓存Form表单的数据,接下来就是根据 key获取对应的值了。

func (c *Context) getFormCache() {    if c.formCache == nil {        c.formCache = make(url.Values)        req := c.Request        if err := req.ParseMultipartForm(c.engine.MaxMultipartMemory); err != nil {            if err != http.ErrNotMultipart {                debugPrint("error on parse multipart form array: %v", err)            }        }        c.formCache = req.PostForm    }}

从以上实现代码可以看到,formCache表单缓存其实也是一个 url.Values,通过调用http.RequestParseMultipartForm对提交的表单解析,获得里面的数据保存在http.RequestPostForm字段中,最后从req.PostForm获取表单数据,赋值给 c.formCache表单缓存即可。

这里需要注意的是保存表单缓存的内存大小,Gin默认给的是32M,通过 const defaultMultipartMemory = 32 << 20 // 32 MB可以看出。

如果你觉得不够,可以提前通过修改MaxMultipartMemory的值增加,比如:

    r := gin.Default()    r.MaxMultipartMemory = 100 << 20

最后的GetPostFormMap方法,其 实现原理和GetQueryMap 一模一样,这里不再赘述,大家可以看下源代码。

小结

不管是查询参数还是表单提交,Gin都为我们做了很好的封装,并且通过缓存提升性能,让我们不再去关注这些具体的细节,可以专注于我们的业务实现,这也是框架的魅力所在。

所以,在我们日常的开发中,不管你是做什么业务,什么语言,还是要尽可能的复用、性能提升等,这样才能逐步的成长。

精彩文章推荐

Golang Gin 实战(五)| 接收数组和map

Golang Gin 实战(四)| URL查询参数的获取和原理分析

Golang Gin 实战(三)| 路由参数

Golang Gin 实战(二)| 简便的Restful API 实现

Golang Gin 实战(一)| 快速安装入门

感谢新老朋友的转发、阅读和点赞支持,给大家抽个现金红包(点击参与),在看到50,下次抽奖金额翻倍!

我有几个的Go语言交流微信群,可以扫码关注公众号flysnow_org或者网站 https://www.flysnow.org/,加我好友,我拉你进来。

扫码关注