首先通過(guò)一個(gè)函數(shù)啟動(dòng)一個(gè)服務(wù)器客税,只提供一個(gè)方法并返回Hello World!
,當(dāng)你在瀏覽器輸入http://127.0.0.1:8080
噪漾,就會(huì)看到Hello World
亿眠。
對(duì)于http.ListenAndServe
來(lái)說(shuō),需要我們提供一個(gè)Addr
和一個(gè)Handler
会傲,所以當(dāng)我們使用Hello
實(shí)現(xiàn)了Handler
的ServeHTTP
方法后锅棕,Hello
就會(huì)被認(rèn)為是一個(gè)Handler
拙泽,并將其提供給http.ListenAndServe
后會(huì)自動(dòng)調(diào)用ServeHTTP
方法。
type Hello struct {
}
func (hello Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World!"))
}
func main() {
http.ListenAndServe(":8080", Hello{})
}
根據(jù)上圖我們看到http
的ListenAndServe
調(diào)用了Server
中的ListenAndServe
方法裸燎,所以以上代碼可以寫(xiě)成顾瞻,再次使用瀏覽器訪問(wèn)http://127.0.0.1:8080
,我們看到了Hello World
德绿。
type Hello struct {
}
func (hello Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World!"))
}
func main() {
server := http.Server{Addr: ":8080", Handler: Hello{}}
server.ListenAndServe()
}
以上的方法我們只能通過(guò)根路徑訪問(wèn)我們想要的結(jié)果荷荤,如何使用不同的路徑訪問(wèn)不同的處理程序呢,你可以寫(xiě)成下面這樣移稳,使用http的Handle
方法蕴纳,把路徑和程序關(guān)聯(lián)起來(lái)并注冊(cè)到程序中。使用瀏覽器訪問(wèn)http://127.0.0.1:8080/hello
个粱,我們看到了Hello World
古毛,那如果訪問(wèn)http://127.0.0.1:8080
會(huì)是什么呢,我們看一下都许,是404 page not found
稻薇。
type Hello struct {
}
func (hello Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World!"))
}
func main() {
http.Handle("/hello", Hello{})
http.ListenAndServe(":8080", nil)
}
好的,我們繼續(xù)看http
的Handle
做了什么胶征,點(diǎn)開(kāi)源碼塞椎,發(fā)現(xiàn)它使用DefaultServeMux
調(diào)用了一個(gè)Handle
函數(shù)
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
那DefaultServeMux
是什么,我們繼續(xù)展開(kāi)睛低,發(fā)現(xiàn)DefaultServeMux
是ServeMux
實(shí)例的一個(gè)指針案狠,而且ServeMux
是一個(gè)struct
,通過(guò)Handle
方法把程序路徑和程序進(jìn)行注冊(cè)暇昂。
// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = &defaultServeMux
var defaultServeMux ServeMux
// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
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
}
}
繼續(xù)觀察這個(gè)struct
莺戒,發(fā)現(xiàn)它實(shí)現(xiàn)了ServeHTTP
,那也就是說(shuō)明ServeMux
是一個(gè)Handler
// ServeHTTP dispatches the request to the handler whose
// pattern most closely matches the request URL.
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
if r.RequestURI == "*" {
if r.ProtoAtLeast(1, 1) {
w.Header().Set("Connection", "close")
}
w.WriteHeader(StatusBadRequest)
return
}
h, _ := mux.Handler(r)
h.ServeHTTP(w, r)
}
根據(jù)以上分析發(fā)現(xiàn)DefaultServeMux
是一個(gè)默認(rèn)的路由程序急波,它將接收到的不同的程序映射到不同的路徑上等待訪問(wèn),同時(shí)它也是一個(gè)Handler
瘪校。
現(xiàn)在我把程序變動(dòng)一下澄暮,這樣也能達(dá)到同樣的效果, 使用瀏覽器訪問(wèn)http://127.0.0.1:8080/hello
依然能看到Hello World
阱扬。
func main() {
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World!"))
})
http.ListenAndServe(":8080", nil)
}
那http
中的HandleFunc
又是什么呢泣懊,我們點(diǎn)進(jìn)去看一下,發(fā)現(xiàn)這個(gè)方法需要傳入func(ResponseWriter, *Request)
類型的函數(shù)麻惶。并且最終被傳入了我們前面提到的ServeMux
的Handle
中馍刮。但是,我們知道只有實(shí)現(xiàn)了ServeHTTP
方法才是Handler
窃蹋,而ServeMux
的Handle
需要一個(gè)Handler
類型的變量卡啰,顯然這個(gè)handler
函數(shù)并不是一個(gè)真正的Handler
静稻。
// HandleFunc registers the handler function for the given pattern.
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
if handler == nil {
panic("http: nil handler")
}
mux.Handle(pattern, HandlerFunc(handler))
}
但是我們看到它被強(qiáng)轉(zhuǎn)成了HandlerFunc
類型。那么我們繼續(xù)查看HandlerFunc
匈辱,HandlerFunc
實(shí)現(xiàn)了ServeHTTP
振湾,那么這就說(shuō)明HandlerFunc
是一個(gè)Handler
,所以最終傳入到ServeMux.Handle
中的HandlerFunc(handler)
是一個(gè)Handler
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
那么我們的代碼也可以寫(xiě)成這樣:
func Hello(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World!"))
}
func main() {
http.HandleFunc("/hello", Hello)
http.ListenAndServe(":8080", nil)
}
或者這樣:
func Hello(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World!"))
}
func main() {
http.Handle("/hello",http.HandlerFunc(Hello))
http.ListenAndServe(":8080", nil)
}
最后http
包中還有幾個(gè)內(nèi)置的Handler
亡脸,您可以自己去探索:
NotFoundHandler
StripPrefix
RedirectHandler
TimeoutHandler
FileServer