开发者

Go-RESTful实现下载功能思路详解

开发者 https://www.devze.com 2022-12-03 14:14 出处:网络 作者: 伯纳乌纯白
目录Go-RESTful实现下载功能下载实现思路文件系统IO:网络IO:服务建立配置路由总结Go-RESTful实现下载功能
目录
  • Go-RESTful实现下载功能
    • 下载实现思路
      • 文件系统IO:
      • 网络IO:
    • 服务建立
      • 配置路由
      • 总结

        Go-RESTful实现下载功能

        下载实现思路

        下图为实现一个文件下载所需要考虑的因素:

        Go-RESTful实现下载功能思路详解

        文件系统IO:

        ● 文件流的读写,其中又包括分文件类型读编程客栈写、文件直接拷贝、借助缓冲区进行IO操作。一般采用直接对二进制文件进行读写,也有特殊情况如zip压缩包

        网络IO:

        ● 文编程件传输的网络协议,是通过http还是tcp进行传输?一般是通过http层面进行读写,

        ● 网络IO中文件主体放在header还编程是body中?文件直接通过操作系统IO还是通过网络IO形成附件供下载

        ● 网络传输的Content-Type,是否符合框架的标准?appclication/octet-stream和其他如applicaiton/zip的区别

        下载的实现流程

        服务建立

        业务背景是需要启动一个服务,使得用户可以通过访问这个服务对某一资源的接口地址进行访问后下载,因此需要先建立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

        配置路由

        建立一个路由如下,同时引入函数的handler:

        ws.Route(ws.GET("/img").To(download.DownLoadRequest).Doc("Add user").
        		Returns(http.StatusOK, "下载成功", ""))
        	//注册webservice
        	restful.Add(ws)
        	logjavascript.Fatjs开发者_JAVA入门al(http.ListenAndServe(":8080", nil)) // 启动监听

        这里需要注意的有几点:

        • restful是接口风格,并不是直接的http方法,因此restful.request并不和http.request等价。要接收http.request的数据应当是对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请求一下这个服务:

        Go-RESTful实现下载功能思路详解

        直接将二进制内容作返回了。此时不要选择Send,选择Send and Download:

        Go-RESTful实现下载功能思路详解

        就会有提示下载附件

        总结

        文件下载的实现实质就是文件流的接收和拷贝,当涉及到不同的文件格式时需要考虑到不同的header和content-type。此外restful中的响应和http的不等价,需要借助writer。

        到此这篇关于Go-RESTful实现下载功能的文章就介绍到这了,更多相关Go RESTful下载内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

        0

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        关注公众号