android 端使用retrofit2.30框架,实现文件和参数上传
代码如下
@Multipart
@POST("/logUpload")
Flowable logUpload(@Part() List files, @PartMap()Map param);
接收端使用的是Go原生的处理器函数
http.HandleFunc("/uploadLog", UploadLog)
func UploadLog(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
fmt.Println("------HEAD------")
for k, v := range r.Header {
fmt.Println(k, ":", v)
}
r.ParseMultipartForm(32 << 20) //最大内存为32M
mf := r.MultipartForm
res0 := mf.Value
fmt.Println("------VALUE--------")
for k, v := range res0 {
fmt.Println(k, ":", v)
}
res1 := mf.File
if res1 != nil {
fmt.Println("------FILE--------")
fmt.Println("len = ", len(res1))
for k, v := range res1 {
fmt.Println(k, ":", v)
}
}
}
}
通过android代码测试结果如下:
------HEAD------
Content-Length : [1038]
Connection : [Keep-Alive]
Accept-Encoding : [gzip]
User-Agent : [okhttp/3.9.0]
Content-Type : [multipart/form-data; boundary=fd8f02e0-a469-49d5-8d7a-9772589d9552]
------VALUE--------
------FILE--------
len = 5
vpnId : [0xc4200b0550]
uId : [0xc4200b0410]
problem : [0xc4200b0460]
contactInfo : [0xc4200b04b0]
appName : [0xc4200b0500]
{"code":200,"msg":"提交成功"}
通过postman,服务器端打印结果如下
Headers
Content-Type:multipart/form-data
------HEAD------
Accept-Encoding : [gzip, deflate]
User-Agent : [okhttp/3.9.0]
Content-Type : [multipart/form-data; boundary=--------------------------015795290054340961609352]
Accept : [*/*]
Content-Length : [26676]
Connection : [keep-alive]
Cache-Control : [no-cache]
Postman-Token : [64af6982-daa7-4cf7-a9f2-93ed2ab12f73]
------VALUE--------
vpnId : [2avpa2dx]
problem : [testaaa]
uId : [23423223]
contactInfo : [1454025171]
appName : [unicorn]
------FILE--------
len = 1
log : [0xc42015a050 0xc42015a0a0 0xc42015a0f0]
{"code":200,"msg":"提交成功"}
通过上面的结果发现android 穿的参数都在
File map[string][]*FileHeader
里面,而postman上传的参数在如下参数里
Value map[string][]string
由于在android使用的是@Part相关的组件,导致,android传的参数和文件都会传到File变量中。
不知道哪位知道参数怎么从File变量中取出来!
下面是抓包对比
android 端抓包
POST /logUpload HTTP/1.1
Content-Type multipart/form-data; boundary=e8e4e506-9e79-4c3d-80ea-e2a20152c914
Content-Length 1054
Host 192.168.6.93:3000
Connection Keep-Alive
Accept-Encoding gzip
User-Agent okhttp/3.9.0
--b74b2f2b-3aa6-43c7-90de-dc1692c5baa4
Content-Disposition: form-data; name="uId"
Content-Transfer-Encoding: binary
Content-Type: text/plain; charset=UTF-8
Content-Length: 35
yk-d094d23be08a4a3e98b5c43c0f585c57
--b74b2f2b-3aa6-43c7-90de-dc1692c5baa4
Content-Disposition: form-data; name="problem"
Content-Transfer-Encoding: binary
Content-Type: text/plain; charset=UTF-8
Content-Length: 27
测试文件上传的时候
--b74b2f2b-3aa6-43c7-90de-dc1692c5baa4
Content-Disposition: form-data; name="contactInfo"
Content-Transfer-Encoding: binary
Content-Type: text/plain; charset=UTF-8
Content-Length: 0
--b74b2f2b-3aa6-43c7-90de-dc1692c5baa4
Content-Disposition: form-data; name="vpnId"
Content-Transfer-Encoding: binary
Content-Type: text/plain; charset=UTF-8
Content-Length: 8
15204876
--b74b2f2b-3aa6-43c7-90de-dc1692c5baa4
Content-Disposition: form-data; name="appName"
Content-Transfer-Encoding: binary
Content-Type: text/plain; charset=UTF-8
Content-Length: 7
unicorn
--b74b2f2b-3aa6-43c7-90de-dc1692c5baa4--
postman抓包
POST /logUpload HTTP/1.1
cache-control no-cache
Postman-Token cb48fe3c-b31a-4038-b604-037016993e19
Content-Type multipart/form-data; boundary=--------------------------799791663844586153468179
User-Agent PostmanRuntime/6.2.5
Accept */*
Host 127.0.0.1:3000
accept-encoding gzip, deflate
content-length 661
Connection keep-alive
----------------------------799791663844586153468179
Content-Disposition: form-data; name="vpnId"
15204876
----------------------------799791663844586153468179
Content-Disposition: form-data; name="problem"
测试文件上传的时候
----------------------------799791663844586153468179
Content-Disposition: form-data; name="uId"
yk-d094d23be08a4a3e98b5c43c0f585c57
----------------------------799791663844586153468179
Content-Disposition: form-data; name="contactInfo"
----------------------------799791663844586153468179
Content-Disposition: form-data; name="appName"
unicorn
----------------------------799791663844586153468179--
最后结论:https://github.com/golang/go/issues/24041