这是我参与「 第五届青训营 」伴学笔记创作活动的第 15 天
前几天在写青训营结课项目的时候,在写到视频投稿的时候,遇到request中body请求信息有一个参数需要file类型。因为用的是go-zero框架,在定义请求消息的时候不能直接使用gin框架,而且go-zero是没有支持file类型的types的。下面就是我的一些解决办法,希望也能帮助到使用go-zero的伙伴。
Go服务器支持以multipart/form-data格式上传文件
http.Request提供了ParseMultipartForm的方法对以multipart/form-data格式传输的数据进行解析,解析即是将数据映射为Request结构的MultipartForm字段的过程:
// $GOROOT/src/net/http/request.go
type Request struct {
... ...
// MultipartForm is the parsed multipart form, including file uploads.
// This field is only available after ParseMultipartForm is called.
// The HTTP client ignores MultipartForm and uses Body instead.
MultipartForm *multipart.Form
... ...
}
multipart.Form代表了一个解析后的multipart/form-data的Body,其结构如下:
// $GOROOT/src/mime/multipart/formdata.go
// Form is a parsed multipart form.
// Its File parts are stored either in memory or on disk,
// and are accessible via the *FileHeader's Open method.
// Its Value parts are stored as strings.
// Both are keyed by field name.
type Form struct {
Value map[string][]string
File map[string][]*FileHeader
}
我们看到这个Form结构由两个map组成,一个map中存放了所有的value part(就像前面的name、age),另外一个map存放了所有的file part(就像前面的part1.txt、part2.png和part3.json)。value part集合没什么可说的,map的key就是每个值分段中的"name";我们的重点在file part上。每个file part对应一组FileHeader,FileHeader的结构如下:
// $GOROOT/src/mime/multipart/formdata.go
type FileHeader struct {
Filename string
Header textproto.MIMEHeader
Size int64
content []byte
tmpfile string
}
每个file part的FileHeader包含五个字段:
- Filename - 上传文件的原始文件名
- Size - 上传文件的大小(单位:字节)
- content - 内存中存储的上传文件的(部分或全部)数据内容
- tmpfile - 在服务器本地的临时文件中存储的部分上传文件的数据内容(如果上传的文件大小大于传给ParseMultipartForm的参数maxMemory,剩余部分存储在临时文件中)
- Header - file part的header内容,它亦是一个map,其结构如下:
// $GOROOT/src/net/textproto/header.go
// A MIMEHeader represents a MIME-style header mapping
// keys to sets of values.
type MIMEHeader map[string][]string
go-zero的真正解决方式
接下来我是在github上找到了答案,链接在这——>POST请求的表单数据 · Issue #421 · zeromicro/go-zero (github.com)
我们可以根据那个回答里面的解决办法,对于.api里可以不写参数。然后修改handle文件就可以啦。 还有一个更官方的go-zreo对于文件上传的解决项目,github.com/zeromicro/z…
以上就是我在解决这个问题,用到的办法。当然我更建议大家看官网链接来修改,这样会更容易理解。