Go-RESTful實現(xiàn)下載功能思路詳解
Go-RESTful實現(xiàn)下載功能
下載實現(xiàn)思路
下圖為實現(xiàn)一個文件下載所需要考慮的因素:
文件系統(tǒng)IO:
● 文件流的讀寫,其中又包括分文件類型讀寫、文件直接拷貝、借助緩沖區(qū)進行IO操作。一般采用直接對二進制文件進行讀寫,也有特殊情況如zip壓縮包
網絡IO:
● 文件傳輸?shù)木W絡協(xié)議,是通過http還是tcp進行傳輸?一般是通過http層面進行讀寫,
● 網絡IO中文件主體放在header還是body中?文件直接通過操作系統(tǒng)IO還是通過網絡IO形成附件供下載
● 網絡傳輸?shù)腃ontent-Type,是否符合框架的標準?appclication/octet-stream和其他如applicaiton/zip的區(qū)別
下載的實現(xiàn)流程
服務建立
業(yè)務背景是需要啟動一個服務,使得用戶可以通過訪問這個服務對某一資源的接口地址進行訪問后下載,因此需要先建立Web Service
ws := new(restful.WebService) ws.Path("/download").Consumes(restful.MIME_JSON,restful.MIME_OCTET). Produces(restful.MIME_JSON, restful.MIME_OCTET)
這里需要注意的是,Consumers和Produces中務必指定MIME類型,否則會按JSON或者XML處理(具體邏輯可以查看相關源碼)。支持的MIME類型如下:
MIME_XML = "application/xml" // Accept or Content-Type used in Consumes() and/or Produces() MIME_JSON = "application/json" // Accept or Content-Type used in Consumes() and/or Produces() MIME_OCTET = "application/octet-stream" // If Content-Type is not present in request, use the default
配置路由
建立一個路由如下,同時引入函數(shù)的handler:
ws.Route(ws.GET("/img").To(download.DownLoadRequest).Doc("Add user"). Returns(http.StatusOK, "下載成功", "")) //注冊webservice restful.Add(ws) log.Fatal(http.ListenAndServe(":8080", nil)) // 啟動監(jiān)聽
這里需要注意的有幾點:
- restful是接口風格,并不是直接的http方法,因此restful.request并不和http.request等價。要接收http.request的數(shù)據(jù)應當是對restful.request的Writer進行操作。
- 一定要引入Content-Disposition,這樣才會使得Get到的二進制文件直接以附件的形式加載出來
- Content-Type一定要是restful支持的MIME類型
func DownLoadRequest(request *restful.Request, response *restful.Response) { // 建立客戶端去Get請求一個資源,此處以一張圖片為例子 client := http.Client{} defer client.CloseIdleConnections() res, err := client.Get("https://img-home.csdnimg.cn/images/20201124032511.png") if err != nil { response.WriteError(http.StatusInternalServerError, errors.New("下載失敗")) } //此處是關鍵 response.ResponseWriter.Header().Set(restful.HEADER_ContentType, restful.MIME_OCTET) response.ResponseWriter.Header().Set("Content-Disposition", "attachment;filename=20201124032511.png") // 將客戶端請求的結果序列化出來 // 不要忘了關閉Body defer res.Body.Close() b, err := ioutil.ReadAll(res.Body) if err != nil { response.WriteError(http.StatusInternalServerError, errors.New("下載失敗")) } _, err = response.ResponseWriter.Write(b) if err != nil { response.WriteError(http.StatusInternalServerError, errors.New("文件讀取失敗")) } }
用Postman請求一下這個服務:
直接將二進制內容作返回了。此時不要選擇Send,選擇Send and Download:
就會有提示下載附件
總結
文件下載的實現(xiàn)實質就是文件流的接收和拷貝,當涉及到不同的文件格式時需要考慮到不同的header和content-type。此外restful中的響應和http的不等價,需要借助writer。
到此這篇關于Go-RESTful實現(xiàn)下載功能的文章就介紹到這了,更多相關Go RESTful下載內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Go條件控制語句詳解(if-else、switch和select)
條件語句用于檢查一個條件是否為真,并根據(jù)條件的真假來決定是否執(zhí)行相應的代碼,下面這篇文章主要給大家介紹了關于Go條件控制語句(if-else、switch和select)的相關資料,需要的朋友可以參考下2024-03-03