golang传递http.ResponseWriter

时间:2012-09-20 19:33:28

标签: go

我正在试图弄清楚是否有可能在编写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函数吐出来。很高兴能够在一个地方设置它并在需要时从中拉出来。对于在相同方面与路由包通信的多个包,这也很好。

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

1 个答案:

答案 0 :(得分:4)

有很多方法可以做到这一点。诀窍是要弄清楚你正在经历的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函数。