Golang学习笔记 - 标准库"net/http"的简析及自制简单路
原文链接:http://targetliu.com/golang-http-router/
源码分析我们知道最简单的建立http服务器代码基本上都是这样的: http.HandleFunc('/',func(w http.ResponseWriter,r *http.Request){ fmt.Fprint(w,"Hello world") }) http.ListenAndServe(":8080",nil) 这样就成功的建立了一个监听 我们顺藤摸瓜来看看 func HandleFunc(pattern string,handler func(ResponseWriter,*Request)) { DefaultServeMux.HandleFunc(pattern,handler) } 这里继续通过调用 type ServeMux struct { mu sync.RWMutex m map[string]muxEntry hosts bool // whether any patterns contain hostnames } type muxEntry struct { explicit bool h Handler pattern string } // NewServeMux allocates and returns a new ServeMux. func NewServeMux() *ServeMux { return new(ServeMux) } // DefaultServeMux is the default ServeMux used by Serve. var DefaultServeMux = &defaultServeMux var defaultServeMux ServeMux
追根究底,发现http服务器收到一条请求后通过 所以,我们就可以理解 继续回到 func (mux *ServeMux) HandleFunc(pattern string,*Request)) { mux.Handle(pattern,HandlerFunc(handler)) }
type HandlerFunc func(ResponseWriter,*Request) // ServeHTTP calls f(w,r). func (f HandlerFunc) ServeHTTP(w ResponseWriter,r *Request) { f(w,r) } 最后到了 至此, 至于请求的时候路由调用,记住通过 自制路由通过以上的分析,我们可以依样画葫芦,实现自己的路由功能。 package route import ( "net/http" "strings" ) //返回一个Router实例 func NewRouter() *Router { return new(Router) } //路由结构体,包含一个记录方法、路径的map type Router struct { Route map[string]map[string]http.HandlerFunc } //实现Handler接口,匹配方法以及路径 func (r *Router) ServeHTTP(w http.ResponseWriter,req *http.Request) { if h,ok := r.Route[req.Method][req.URL.String()]; ok { h(w,req) } } //根据方法、路径将方法注册到路由 func (r *Router) HandleFunc(method,path string,f http.HandlerFunc) { method = strings.ToUpper(method) if r.Route == nil { r.Route = make(map[string]map[string]http.HandlerFunc) } if r.Route[method] == nil { r.Route[method] = make(map[string]http.HandlerFunc) } r.Route[method][path] = f } 使用: r := route.NewRouter() r.HandleFunc("GET","/",r *http.Request) { fmt.Fprint(w,"Hello Get!") }) r.HandleFunc("POST","hello POST!") }) http.ListenAndServe(":8080",r) 这个例子只是依样画葫芦的简单功能实现。 一个完整的路由框架应该包含更复杂的匹配、错误检测等等功能,大家可以试着自己动手试试。 阅读源码和重复造轮子都是学习的方法。 最后,欢迎大家关注我的博客http://targetliu.com/ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |