[英]How to get file posted from JSON in go gin?
I want to save image file posted by JSON.我想保存由 JSON 发布的图像文件。
Here is the struct of the post:这是帖子的结构:
type Article struct {
Title string `json:"title"`
Body string `json:"body"`
File []byte `json:"file"`
}
And the handler is:处理程序是:
func PostHandler(c *gin.Context) {
var err error
var json Article
err = c.BindJSON(&json)
if err != nil {
log.Panic(err)
}
//handle photo upload
var filename string
file, header, err := json.File //assignment count mismatch: 3 = 1
if err != nil {
fmt.Println(err)
filename = ""
} else {
data, err := ioutil.ReadAll(file)
if err != nil {
fmt.Println(err)
return
}
filename = path.Join("media", +shared.RandString(5)+path.Ext(header.Filename))
err = ioutil.WriteFile(filename, data, 0777)
if err != nil {
io.WriteString(w, err.Error())
return
}
}
...
But I get但我明白了
assignment count mismatch: 3 = 1
分配计数不匹配:3 = 1
I copied the file handling part from a working multipart form handler which worked fine but apparently,我从一个工作正常的多部分表单处理程序中复制了文件处理部分,但显然,
file, header, err := r.FormFile("uploadfile")
can not be translated into JSON handling.不能翻译成JSON处理。
I have looked at gin docs but could not find examples involving json file handling.我查看了 gin 文档,但找不到涉及 json 文件处理的示例。 So how can I fix this?
那么我该如何解决呢?
I think your question is "Using Gin, how do I get an uploaded file?".我认为您的问题是“使用 Gin,如何获取上传的文件?”。 Most developers don't upload files with JSON encoding, which could be done but requires the file to be included as a base64 string (and increases the file size about 33%).
大多数开发人员不上传使用 JSON 编码的文件,这可以做到,但需要将文件作为 base64 字符串包含在内(并增加文件大小约 33%)。
The common (and more efficient) practice is to upload the file using the "multipart/form-data" encoding.常见(且更有效)的做法是使用“multipart/form-data”编码上传文件。 The code that others provided
file, header, err:= c.Request.FormFile("file")
works, but that hijacks the underlining "net/http" package that Gin extends.其他人提供的代码
file, header, err:= c.Request.FormFile("file")
有效,但它劫持了 Gin 扩展的下划线“net/http”包。
My recommendation is to use ShouldBind
, but you can also use the FormFile
orMultipartForm
methods provided by the Gin package.我的建议是使用
ShouldBind
,但您也可以使用 Gin 包提供的FormFile
或MultipartForm
方法。
Examples below.下面的例子。 Similar (but less detailed) explanations are also offered on the Gin page https://github.com/gin-gonic/gin#model-binding-and-validation and https://github.com/gin-gonic/gin#upload-files .
Gin 页面https://github.com/gin-gonic/gin#model-binding-and-validation和https://github.com/gin-gonic/gin#上也提供了类似(但不太详细)的解释上传文件。
HTML HTML
<form action="/upload" method="POST">
<input type="file" name="file">
<input type="submit">
</form>
Curl卷曲
curl -X POST http://localhost:8080/upload \
-F "file=../path-to-file/file.zip" \
-H "Content-Type: multipart/form-data"
Go走
package main
import (
"github.com/gin-gonic/gin"
"log"
"net/http"
"io/ioutil"
)
type Form struct {
File *multipart.FileHeader `form:"file" binding:"required"`
}
func main() {
router := gin.Default()
// Set a lower memory limit for multipart forms (default is 32 MiB)
// router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
// Using `ShouldBind`
// --------------------
var form Form
_ := c.ShouldBind(&form)
// Get raw file bytes - no reader method
// openedFile, _ := form.File.Open()
// file, _ := ioutil.ReadAll(openedFile)
// Upload to disk
// `form.File` has io.reader method
// c.SaveUploadedFile(form.File, path)
// --------------------
// Using `FormFile`
// --------------------
// formFile, _ := c.FormFile("file")
// Get raw file bytes - no reader method
// openedFile, _ := formFile.Open()
// file, _ := ioutil.ReadAll(openedFile)
// Upload to disk
// `formFile` has io.reader method
// c.SaveUploadedFile(formFile, path)
// --------------------
c.String(http.StatusOK, "Files uploaded")
})
// Listen and serve on 0.0.0.0:8080
router.Run(":8080")
}
HTML HTML
<form action="/upload" method="POST" multiple="multiple">
<input type="file" name="files">
<input type="submit">
</form>
Curl卷曲
curl -X POST http://localhost:8080/upload \
-F "files=../path-to-file/file1.zip" \
-F "files=../path-to-file/file2.zip" \
-H "Content-Type: multipart/form-data"
Go走
package main
import (
"github.com/gin-gonic/gin"
"log"
"net/http"
"io/ioutil"
)
type Form struct {
Files []*multipart.FileHeader `form:"files" binding:"required"`
}
func main() {
router := gin.Default()
// Set a lower memory limit for multipart forms (default is 32 MiB)
// router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
// Using `ShouldBind`
// --------------------
var form Form
_ := c.ShouldBind(&form)
// for _, formFile := range form.Files {
// Get raw file bytes - no reader method
// openedFile, _ := formFile.Open()
// file, _ := ioutil.ReadAll(openedFile)
// Upload to disk
// `formFile` has io.reader method
// c.SaveUploadedFile(formFile, path)
// }
// --------------------
// Using `MultipartForm`
// --------------------
// form, _ := c.MultipartForm()
// formFiles, _ := form["files[]"]
// for _, formFile := range formFiles {
// Get raw file bytes - no reader method
// openedFile, _ := formFile.Open()
// file, _ := ioutil.ReadAll(openedFile)
// Upload to disk
// `formFile` has io.reader method
// c.SaveUploadedFile(formFile, path)
// }
// --------------------
c.String(http.StatusOK, "Files uploaded")
})
// Listen and serve on 0.0.0.0:8080
router.Run(":8080")
}
In your code you say var json Article
where type article is defined as在您的代码中,您说
var json Article
类型文章定义为
type Article struct {
Title string `json:"title"`
Body string `json:"body"`
File []byte `json:"file"`
}
And File is of type []byte
. File 是
[]byte
类型。 Type byte doesn't return anything other than what it holds类型 byte 除了它所持有的内容外不返回任何东西
Your Article.File
is not the same as r.FormFile
where FormFile
is a method that returns 3 items您的
Article.File
与r.FormFile
,其中FormFile
是返回 3 个项目的方法
So file, header, err:= json.File
isn't file, header, err:= r.FormFile("foo")
所以
file, header, err:= json.File
不是file, header, err:= r.FormFile("foo")
See the implementation and method description from godocs -> here请参阅 godocs ->此处的实现和方法描述
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.