goframe框架实现文件下载功能

goframe框架实现文件下载功能

最近在使用goframe框架编写微服务,接到pm的新需求,要求实现文件下载功能,但是翻看了goframe框架的官方技术文档,没有找到类似的案例。于是,谷歌了一下golang语言的文件下载功能实现的代码,结合goframe框架的源码,实现了goframe框架的文件下载。


探索过程

golang的实现方案

func FileDownload(w http.ResponseWriter, r *http.Request) {
    filename := get_filename_from_request(r)

    file, _ := os.Open(filename)
    defer file.Close()

    fileHeader := make([]byte, 512)
    file.Read(fileHeader)

    fileStat, _ := file.Stat()

    w.Header().Set("Content-Disposition", "attachment; filename=" + filename)
    w.Header().Set("Content-Type", http.DetectContentType(fileHeader))
    w.Header().Set("Content-Length", strconv.FormatInt(fileStat.Size(), 10))

    file.Seek(0, 0)
    io.Copy(w, file)

    return
}

从上面的代码中我们能够发现,核心的代码是http.ResponseWriter在header中设置了Content-Disposition,而http的header中的key的详解可以参考http协议规范。我们再来看看goframe框架中的http.ResponseWriter在哪。

标准的goframe api代码

func (c *Controller) Index(r *ghttp.Request) {
	r.Response.Write("hello world")
}

我们追踪一下r.Response的定义

ghttp_request.go

type Request struct {
	*http.Request
	Server          *Server                // Server.
	Cookie          *Cookie                // Cookie.
	Session         *gsession.Session      // Session.
	Response        *Response              // Corresponding Response of this request.
	Router          *Router                // Matched Router for this request. Note that it's not available in HOOK handler.
	EnterTime       int64                  // Request starting time in microseconds.
	LeaveTime       int64                  // Request ending time in microseconds.
	Middleware      *Middleware            // Middleware manager.
	StaticFile      *StaticFile            // Static file object for static file serving.
	context         context.Context        // Custom context for internal usage purpose.
	handlers        []*handlerParsedItem   // All matched handlers containing handler, hook and middleware for this request.
	hasHookHandler  bool                   // A bool marking whether there's hook handler in the handlers for performance purpose.
	hasServeHandler bool                   // A bool marking whether there's serving handler in the handlers for performance purpose.
	parsedQuery     bool                   // A bool marking whether the GET parameters parsed.
	parsedBody      bool                   // A bool marking whether the request body parsed.
	parsedForm      bool                   // A bool marking whether request Form parsed for HTTP method PUT, POST, PATCH.
	paramsMap       map[string]interface{} // Custom parameters map.
	routerMap       map[string]string      // Router parameters map, which might be nil if there're no router parameters.
	queryMap        map[string]interface{} // Query parameters map, which is nil if there's no query string.
	formMap         map[string]interface{} // Form parameters map, which is nil if there's no form data from client.
	bodyMap         map[string]interface{} // Body parameters map, which might be nil if there're no body content.
	error           error                  // Current executing error of the request.
	exit            bool                   // A bool marking whether current request is exited.
	parsedHost      string                 // The parsed host name for current host used by GetHost function.
	clientIp        string                 // The parsed client ip for current host used by GetClientIp function.
	bodyContent     []byte                 // Request body content.
	isFileRequest   bool                   // A bool marking whether current request is file serving.
	viewObject      *gview.View            // Custom template view engine object for this response.
	viewParams      gview.Params           // Custom template view variables for this response.
}

ghttp_response.go

type Response struct {
	*ResponseWriter                 // Underlying ResponseWriter.
	Server          *Server         // Parent server.
	Writer          *ResponseWriter // Alias of ResponseWriter.
	Request         *Request        // According request.
}

ghttp_response_writer.go

type ResponseWriter struct {
	Status      int                 // HTTP status.
	writer      http.ResponseWriter // The underlying ResponseWriter.
	buffer      *bytes.Buffer       // The output buffer.
	hijacked    bool                // Mark this request is hijacked or not.
	wroteHeader bool                // Is header wrote or not, avoiding error: superfluous/multiple response.WriteHeader call.
}

至此我们发现ghttp模块实现了强大的http server。可以了解怎么去实现文件下载的功能了。

代码实现

func JsonFile(r *ghttp.Request, data interface{}, filename string) {
	// 这里偷懒,content-type写死了
	r.Response.Header().Set("Content-Type", "application/octet-stream")
	// 注意后面的attachment和filename,否则下载的时候不能自动命名文件名和文件后缀
	r.Response.Header().Set("Content-Disposition", "attachment; filename="+filename)
	r.Response.Write(data)
	r.Exit()
}

关键代码:r.Response.Header().Set("Content-Disposition", "attachment; filename="+filename)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值