来看一段简单的代码,这是入门学习go http包的常见实例。简单的几行代码就完成了一个http服务器的构建,go http包的强大可见一斑。
func handleWeb(w http.ResponseWriter, r *http.Request){
fmt.Fprintf(w, "Hello world!")
}
func main(){
http.HandleFunc("/", handleWeb)
http.ListenAndServe(":8008", nil)
}
我们首先分析http.HandleFunc这个函数到底做了哪些事情。
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}
http.HandleFunc内部通过默认路由DefaultServeMux来调用HandleFunc函数:
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
if handler == nil {
panic("http: nil handler")
}
mux.Handle(pattern, HandlerFunc(handler))
}
注意看上面代码最后一行,将传入的handler函数(函数签名为(w http.ResponseWriter, r *http.Request))通过HandlerFunc将其强制类型转换为HandlerFunc类型。而HandlerFunc本身实现了ServeHTTP方法,因此它是一个Handler类型。
func (mux *ServeMux) Handle(pattern string, handler Handler) {
mux.mu.Lock()
defer mux.mu.Unlock()
if pattern == "" {
panic("http: invalid pattern")
}
if handler == nil {
panic("http: nil handler")
}
if _, exist := mux.m[pattern]; exist {
panic("http: multiple registrations for " + pattern)
}
if mux.m == nil {
mux.m = make(map[string]muxEntry)
}
e := muxEntry{h: handler, pattern: pattern}
mux.m[pattern] = e
if pattern[len(pattern)-1] == '/' {
mux.es = appendSorted(mux.es, e)
}
if pattern[0] != '/' {
mux.hosts = true
}
}
mux.Handle函数则将匹配的字符串和对应的Handler作为一项k-v添加到内部成员m中去,进而完成了路由注册。m的类型为map[string]muxEntry,它保存了字符串和对应的实体muxEntry。
接下来就要进行http服务的监听了。