文件上传与接收的整个流程

2018-10-18  本文已影响0人  刺客的幻影

人生如逆旅,我亦是行人

今天一个后端同学问我客户端图片上传如何处理,把思路和代码告诉他后,但是他对后端如何处理文件数据还是不太了解,正好我对后端的文件接收也没有处理过,借此机会自己动手走一次前后端上传和接收的整个流程,换个角度看看问题。客户端代码以kotlin为例,服务端代码以go为例:

一. 网段的配置

1、首先保证手机和mac在同一个wifi下,终端输入ifconfig获取本机ip


image.png

2、手机设置wifi为为手动代理,ip填写刚才获取到的mac地址,端口填写7777


image.png

二、Android端文件的上传(以图片为例):

详细情况可以参考我另外一篇博客:https://www.jianshu.com/p/3a665b2e6d5b

 @Multipart
 @POST("api/rq_info_add_submit")
 fun upload(@Part() parts: List<MultipartBody.Part>): Observable<HttpResult<String>>


 private fun uploadImages(imgPaths: List<String>) {
        val builder = MultipartBody.Builder()
        builder.setType(MultipartBody.FORM)
        val imgFile = File(imgPaths[0])
        val imgBody = RequestBody.create(MediaType.parse("multipart/form-data"), imgFile1)
        builder.addFormDataPart("first_photo", imgFile.name, imgBody)
        var map: TreeMap<String, String> = HttpClient.instance.getBaseMap(true)
        map["type"] = type.toString()
        map["name"] = name
        map["number"] = number
        map = DataHandler.encryptParams(map) as TreeMap<String, String>
        map.forEach {
            builder.addFormDataPart(it.key, it.value)
        }
        val parts = builder.build().parts()
        HttpClient.instance.upload(parts)
                .compose(SchedulerHelpers.io2main())
                .bindToLifecycle(this)
                .subscribe {
             
                }
    }

三、服务端接收并解析:

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "os"
)

func httpHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("hello"))
    log.Println(r)
    r.ParseMultipartForm(32 << 20)
    file, handler, err := r.FormFile("images")//获取MultipartForm中字段为images的文件
    if err != nil {
        fmt.Println(err)
        return
    }
    defer file.Close()
    fmt.Fprintf(w, "%v", handler.Header)
    f, err := os.OpenFile("./test.jpg", os.O_WRONLY|os.O_CREATE, 0666)
    //将文件保存为test.jpg
    if err != nil {
        fmt.Println(err)
        return
    }
    defer f.Close()
    io.Copy(f, file)

}

func main() {
    http.HandleFunc("/api/rq_info_add_submit", httpHandler)
    http.ListenAndServe("0.0.0.0:7777", nil)
}

获取GET请求参数

queryForm, err := url.ParseQuery(r.URL.RawQuery)
if err == nil && len(queryForm["id"]) > 0 {
    fmt.Fprintln(w, queryForm["id"][0])
}

获取POST请求参数

application/x-www-form-urlencoded 格式
r.ParseForm()
// 法一
r.PostForm["id"][0]
// 法二
r.PostFormValue["id"]
multipart/form-data 格式
普通参数
r.ParseMultipartForm(32<<20)
// 法一
r.PostForm["id"][0]
// 法二
r.PostFormValue["id"]
文件
r.ParseMultipartForm(32 << 20)
    file, handler, err := r.FormFile("file")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer file.Close()
    fmt.Fprintf(w, "%v", handler.Header)
    f, err := os.OpenFile("./test.txt", os.O_WRONLY|os.O_CREATE, 0666)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer f.Close()
    io.Copy(f, file)
application/json 格式
type User struct {
    Name string `json:"username"`
    Pwd string `json:"password"`
}

type RetMessage struct {
    Code string `json:"code"`
    Msg string  `json:"msg"`
}

func processJson(w http.ResponseWriter, r *http.Request) {
    var u User
    if r.Body == nil {
        http.Error(w, "Please send a request body", 400)
        return
    }
    err := json.NewDecoder(r.Body).Decode(&u)
    if err != nil {
        http.Error(w, err.Error(), 400)
        return
    }
    fmt.Println(u)
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(RetMessage{"200", "ok"})
}
上一篇下一篇

猜你喜欢

热点阅读