【问题标题】:golang passing http.ResponseWritergolang 传递 http.ResponseWriter
【发布时间】:2012-09-20 19:33:27
【问题描述】:

我试图弄清楚在编写 Web 应用程序时是否可以不必在任何地方传递 http.ResponseWriter。我正在建立一个简单的 mvc web 框架,我发现自己必须通过各种函数传递 http.ResponseWriter,而它只用于让我们说最后一个函数。

路由包

// Struct containing http requests and variables
type UrlInfo struct {
    Res http.ResponseWriter
    Req *http.Request
    Vars map[string]string
}

func HandleFunc(handlepath string, runfunc func(*UrlInfo)) {
    // Set handler and setup struct
    http.HandleFunc(getHandlePath(handlepath), func(w http.ResponseWriter, r *http.Request) {
        url := new(UrlInfo)
        url.Res = w
        url.Req = r
        url.Vars = parsePathVars(r.URL.Path, handlepath)

        runfunc(url)
    })
}

// Parse file and send to responsewriter
func View(w http.ResponseWriter, path string, data interface{}) {
    // Go grab file from views folder
    temp, err := template.ParseFiles(path+".html")
    if err != nil {
        // Couldnt find html file send error
        http.Error(w, err.Error(), http.StatusInternalServerError)
    } else {
        temp.ExecuteTemplate(w, temp.Name(), data)
    }
}

控制器包

import (
    "routes"
)

func init() {
    // Build handlefunc
    routes.HandleFunc("/home/", home)
}

func home(urlinfo *routes.UrlInfo) {
    info := make(map[string]string)
    info["Title"] = urlinfo.Vars["title"]
    info["Body"] = "Body Info"

    gi.View(urlinfo.Res, "pages/about", info)
}

我不想在 home 函数中传递任何东西,这样我就可以再次将它传递给 view 函数以吐出。能够将它设置在一个地方并在需要时从中拉出会很好。这对于在同一方面与路由包进行通信的多个包来说也很好。

欢迎提出任何想法、提示或技巧。谢谢。

【问题讨论】:

    标签: go


    【解决方案1】:

    有多种方法可以做到这一点。诀窍是从您正在通过的 ResponseWriter 中找出您真正需要什么。听起来你只需要练习一点函数组合。

    更改您的设计,以便 View 返回一个 io.Reader,然后您可以将一个错误通过管道传输到 ResponseWriter。这是一个完全未经测试的示例:

    func View(path string, data interface{}) (io.Reader, error) {
        // Go grab file from views folder
        temp, err := template.ParseFiles(path+".html")
        if err != nil {
            // Couldnt find html file send error
           return nil, err
        } else {
            buf := bytes.Buffer()
            temp.ExecuteTemplate(buf, temp.Name(), data)
            return buf
        }
    }
    
    func HandleFunc(handlepath string, runfunc func(*UrlInfo) (io.Reader, error)) {
        // Set handler and setup struct
        http.HandleFunc(getHandlePath(handlepath),
                        func(w http.ResponseWriter, r *http.Request) {
            url := new(UrlInfo)
            url.Res = w
            url.Req = r
            url.Vars = parsePathVars(r.URL.Path, handlepath)
    
            rdr, err := runfunc(url)
            io.Copy(w, rdr);
        })
    }
    

    有了这个,唯一需要担心 http ResponseWriter 的就是你的 HandleFunc 函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-24
      • 1970-01-01
      • 2018-12-27
      • 2018-10-22
      • 2016-11-01
      • 2016-04-23
      • 2018-04-01
      • 1970-01-01
      相关资源
      最近更新 更多