go gin multipart
原文链接: go gin multipart
如何获取所有的请求参数
这个其实和gin框架没有啥关系,我刚开始使用的时候以为使用request.ParseForm,然后在request.Form中就能得到了。
结果发现当我的Content-type为multipart/form-data的时候,竟然解析不到数据。
追到ParseForm里面发现,http/request.go里面有这么一个部分代码
case ct == "multipart/form-data":
// handled by ParseMultipartForm (which is calling us, or should be)
// TODO(bradfitz): there are too many possible
// orders to call too many functions here.
// Clean this up and write more tests.
// request_test.go contains the start of this,
// in TestParseMultipartFormOrder and others.
}
我的golang版本是1.11.4。当content-type为multipart/form-data的时候是空的调用的。
当然注释也写很清楚了,建议使用ParseMultipartForm
所以获取http参数的函数我就写成这个样子:
// 这个函数只返回json化之后的数据,且不处理错误,错误就返回空字符串
func getArgs(c *gin.Context) []byte {
if c.ContentType() == "multipart/form-data" {
c.Request.ParseMultipartForm(defaultMemory)
} else {
c.Request.ParseForm()
}
args, _ := json.Marshal(c.Request.Form)
return args
}
router.POST("/upload", func(c *gin.Context) {
c.Request.ParseMultipartForm(202020)
if c.ContentType() == "multipart/form-data" {
c.Request.ParseMultipartForm(1024 * 1024)
} else {
c.Request.ParseForm()
}
// args, _ := json.Marshal(c.Request.Form)
fmt.Println("c.Request.Form\n", c.Request.Form)
// fmt.Println("c.Request.PostForm\n", c.Request.PostForm)
// fmt.Println("c.Request.MultipartForm.Value\n", c.Request.MultipartForm.Value)
// c.Request.Form
// map[battery:[3.998] dev_id:[356802050038933] firmware_version:[1.8.16_CAM100S21] signal:[-72dbm] temp_cpu:[42] temp_env:[42] timestamp:[1596616340]]
// c.Request.PostForm
// map[battery:[3.998] dev_id:[356802050038933] firmware_version:[1.8.16_CAM100S21] signal:[-72dbm] temp_cpu:[42] temp_env:[42] timestamp:[1596616340]]
// c.Request.MultipartForm.Value
// map[battery:[3.998] dev_id:[356802050038933] firmware_version:[1.8.16_CAM100S21] signal:[-72dbm] temp_cpu:[42] temp_env:[42] timestamp:[1596616340]]
for key, file := range c.Request.MultipartForm.File {
for k, f := range file {
fmt.Println("c.Request.MultipartForm.File", key, k, f.Filename)
}
}
// c.Request.MultipartForm.File upload0 0 20200805163835-30.jpg
golang gin 打印所有的参数信息 gintest
package middlewares
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
const DefaultMemory = 32 * 1024 * 1024
//一些中间件 备用
// GetHeaders ...
func GetHeaders(head http.Header) map[string]string {
hdr := make(map[string]string, len(head))
for k, v := range head {
hdr[k] = v[0]
}
return hdr
}
// GetIP ...
func GetIP(c *gin.Context) string {
ip := c.ClientIP()
return ip
}
// GetMultiPartFormValue ...
func GetMultiPartFormValue(c *http.Request) interface{} {
var requestBody interface{}
multipartForm := make(map[string]interface{})
if err := c.ParseMultipartForm(DefaultMemory); err != nil {
// handle error
}
if c.MultipartForm != nil {
for key, values := range c.MultipartForm.Value {
multipartForm[key] = strings.Join(values, "")
}
for key, file := range c.MultipartForm.File {
for k, f := range file {
formKey := fmt.Sprintf("%s%d", key, k)
multipartForm[formKey] = map[string]interface{}{"filename": f.Filename, "size": f.Size}
}
}
if len(multipartForm) > 0 {
requestBody = multipartForm
}
}
return requestBody
}
// GetFormBody ...
func GetFormBody(c *http.Request) interface{} {
var requestBody interface{}
form := make(map[string]string)
if err := c.ParseForm(); err != nil {
// handle error
}
for key, values := range c.PostForm {
form[key] = strings.Join(values, "")
}
if len(form) > 0 {
requestBody = form
}
return requestBody
}
// GetRequestBody ...
func GetRequestBody(c *gin.Context) interface{} {
//multiPartFormValue := GetMultiPartFormValue(c.Request)
//if multiPartFormValue != nil {
// return multiPartFormValue
//}
//
//formBody := GetFormBody(c.Request)
//if formBody != nil {
// return formBody
//}
method := c.Request.Method
if method == "GET" {
return nil
}
contentType := c.ContentType()
body := c.Request.Body
var model interface{}
bodyContent, err := ioutil.ReadAll(body)
if err != nil {
return model
}
// Restore the io.ReadCloser to its original state
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyContent))
switch contentType {
case binding.MIMEJSON:
json.Unmarshal(bodyContent, &model)
return model
default:
model = string(bodyContent)
return model
}
}