doujia2090
2012-09-20 19:33
浏览 371
已采纳

golang传递http.ResponseWriter

I am trying to figure out if its possible to not have to pass along the http.ResponseWriter everywhere i go when programming a web application. I am setting up a simple mvc web framework and i find myself having to pass the http.ResponseWriter through various functions when its only used in lets say the last function.

Routes package

// 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)
    }
}

Controller package

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)
}

I would like to not have to pass anything in the home function just so i can pass it again to the view function to spit out. Would be nice to be able to set it in one place and pull from it whenever needed. This would also nice in regard to multiple packages that communicate to the routes package in the same regard.

Any and all thoughts, tips or tricks are welcome. Thanks.

图片转代码服务由CSDN问答提供 功能建议

我试图弄清楚是否有必要不必在编程时遍历http.ResponseWriter 网络应用程序。 我正在建立一个简单的mvc Web框架,当不得不说最后一个函数时,我不得不通过各种函数传递http.ResponseWriter。

路由软件包

  //包含http请求和变量的结构
type UrlInfo struct {
 Res http.ResponseWriter 
 要求* http.Request 
 Vars map [string] string 
} 
 
func HandleFunc(handlepath string,runfunc func(* UrlInfo)){
 //设置处理程序和设置结构
 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)
})
} 
 
 //解析文件并发送到responsewriter 
func View(w http.ResponseWriter,路径字符串,数据接口{})  {
 //从视图文件夹中获取文件
临时,错误:= template.ParseFiles(path +“。html”)
如果错误!=无{
 //无法找到html文件发送错误
 http。  Error(w,err.Error(),http.StatusInternalServerError)
}其他{
 temp.ExecuteTemplate(w,temp.Name(),data)
} 
} 
   
 
 

CONTR oller包

  import(
“ routes” 
)
 
func init(){
 //构建handlefunc 
 route.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条回答 默认 最新

  • dongwu8050 2012-09-21 04:26
    已采纳

    There are a number of ways you can do this. The trick is to figure out what is you actually need from the ResponseWriter you are passing through. It sounds like you just need to exercise a little function composition.

    Change your design so that the View returns an io.Reader, and an error that you can then pipe into the ResponseWriter. Here's a completely untested example:

    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);
        })
    }
    

    With this the only thing that has to worry about the http ResponseWriter is your HandleFunc function.

    已采纳该答案
    打赏 评论

相关推荐 更多相似问题