net/http 包
如果想使用Go建立一個(gè)web程序和web APIs,或者建立一個(gè)簡(jiǎn)單的HTTP服務(wù)器,最重要的就是標(biāo)準(zhǔn)庫的net/http包,提供了web應(yīng)用的全部基礎(chǔ)組件.當(dāng)然我們也可以進(jìn)行拓展,開發(fā)出自己的框架.目前有beego,revel,martini.對(duì)于web開發(fā),net/http,html/template是最主要的包,使用這兩個(gè)基礎(chǔ)的包,就能開發(fā)出全部功能的web應(yīng)用.
net/http包有兩個(gè)主要的組件:ServeMux(路由),Handler(句柄)
ServeMux
ServeMux 多路復(fù)用器(HTTP請(qǐng)求路由),對(duì)應(yīng)著客戶端的每個(gè)請(qǐng)求,從而調(diào)用請(qǐng)求的相應(yīng)的handler.
Handler
Handlers主要是響應(yīng)請(qǐng)求,對(duì)響應(yīng)頭和主體寫入數(shù)據(jù)(就是服務(wù)器對(duì)一個(gè)客戶端過來的一個(gè)請(qǐng)求進(jìn)行相應(yīng)的操作,比如輸出信息給客戶端,找不到對(duì)應(yīng)的服務(wù)等).在Go,任何的對(duì)象都可以作為一個(gè)handler,這得益于Go語言的出色的面向接口思想.任意的對(duì)象(struct,function常見)只要實(shí)現(xiàn)了http.Handler接口,就能作為http請(qǐng)求的handler.
http.Handler接口
type Handler interface{
ServeHTTP(ResponseWrite,* Request)
}
這是一些共用的handler
- FileServer
- NotFoundHandler
- RedirectHandler
- StripPrefix
- TimeoutHandler
自定義Handlers
type messageHandler struct{
message string
}
//implement http.Handler interface
func (m *messageHandler)ServeHTTP(w http.ResponseWrite,r *http.Request){
fmt.Fprintf(w,m.message)
}
messageHandler 結(jié)構(gòu)體實(shí)現(xiàn)了http.Handler接口,可以作為http請(qǐng)求的handler
- 使用自定義的Handler
// book
package main
import (
"fmt"
"log"
"net/http"
)
type messageHandler struct {
message string
}
//implement http.Handler interface
func (m *messageHandler) ServeHTTP(w http.ResponseWrite, r *http.Request) {
fmt.Fprintf(w, m.message)
}
func main() {
mux := http.NewServeMux()
mh1 := &messageHandler{"歡迎使用Go"}
mux.Handle("/welcome", mh1)
mh2 := &messageHandler{"Go這的很酷啊!"}
mux.Handle("/message", mh2)
log.Println("Listening...")
http.ListenAndServe(":9090", mux)
}
在瀏覽器輸入對(duì)應(yīng)的路徑就能打印出相應(yīng)的信息
使用方法(函數(shù))作為 Handlers
在上面的例子,使用結(jié)構(gòu)體struct,實(shí)現(xiàn)了http.handler接口,從而作為了handler,比較"麻煩",還有更好的方式來實(shí)現(xiàn):使用函數(shù)作為handler,只要這個(gè)函數(shù)的返回值是http.Handler
1.http.HandlerFunc類型
可以使用http.HandlerFunc類型來得到一個(gè)HTTP的handler,可以把任意一個(gè)有func(http.ResponseWriter, http.Request)標(biāo)示的函數(shù)轉(zhuǎn)換為一個(gè)HandlerFunc. HandlerFunc類型
內(nèi)置了方法ServeHTTP(http.ResponseWriter,http.Request),所以符合http.Handler接口,作為一個(gè)HTTP的handler
栗子如下
// book
package main
import (
"fmt"
"log"
"net/http"
)
func messageHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "歡迎使用Go開發(fā)")
}
func main() {
mux := http.NewServeMux()
//Convert the messageHandler function to a HandlerFunc type
mh := http.HandlerFunc(messageHandler)
mux.Handle("/welcome", mh)
log.Println("Listening...")
http.ListenAndServe(":9090", mux)
}
有一種情況:假如想傳遞數(shù)據(jù)庫的鏈接對(duì)象到一個(gè)handler函數(shù)中,從而在函數(shù)重用他.可以寫一個(gè)函數(shù),用一個(gè)參數(shù)接收值,然后返回值是http.Handler.在Go中,可以使用閉包(closure,匿名函數(shù)).
代碼栗子
package main
import (
"fmt"
"log"
"net/http"
)
//Writing Handler Logic into a Closure
func messageHandler(message string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, message)
})
}
func main() {
mux := http.NewServeMux()
mux.Handle("/welcome", messageHandler("歡迎使用Go"))
mux.Handle("/message", messageHandler("Hello Go!"))
log.Println("Listening...")
http.ListenAndServe(":9090", mux)
}
這種方式對(duì)于實(shí)際工作中非常有用,可以為程序的handler函數(shù)的上下文,提供有用的值.(明天學(xué)習(xí)Web Development with Go ServeMux.HandleFunc Function)