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

`