花了一個星期學習文件服務器,老是在一些地方搞混,整理一下所學的,清晰了不少。
學Go半個月,還有很多不懂的地方,有理解錯誤的,還望高手指出。
注:以下代碼中,w為http.ResponseWriter類型, r為*http.Request類型
1、先該清楚一些類型的意義:
Handler:處理請求和生成返回的接口。其實就是接口。
ServerMux:路由,也是一種Handler。還是接口。
Request:用戶的請求信息,用來解析用戶的請求信息包括,POST、GET、Cookie、URL等信息。
Response:服務器需要反饋給用戶端的信息。
ResponseWriter:生成Response的接口。也還是接口
Conn:網絡連接。
ServerMux有map表,map的key是r.URL.String(),而Value記錄的是一個方法,這個方法與ServeHTTP是一樣的,也叫HandlerFunc。另一個方法是Handle 用來注冊HandlerFunc。
ServeMUx實現Handler接口,充當http.ListenAndServe()的第二個參數。
http.ListenAndServe()的第二個參數是Handle接口,實現配置外部路由器(也就是非默認的路由器)。
2、設置路由的方法:
(1)
func fooHandler(w,r){ }
http.Handle("/foo", fooHandler)//此處是http.Handle,而不是http.Handler
(2)
http.HandleFunc("/foo", func(w,r){
//處理
})
以上配置的是默認路由
如果自己使用了ServeMux作為路由,就得用其他配置方法了
(3)配置ServeMux路由
1)
mux:=http.NewServeMux()
mux.Handle("/foo",&fooHandler{})//第二個參數是一個Handler,可以是定義一個Handler接口,也可以是返回Handler的函數。比如:StripPrefix(prefix string, h Handler) Handler {}等。
type fooHandler struct{}
func (*fooHandler)serveHTTP(w,r){
//處理
}
2)
mux:=http.NewServeMux()
mux.HandleFunc("/foo", fooHandler)
func fooHandler(w,r){
//處理
}
3)
Var mux map[string] func(w,r)
mux=make[string]func(w,r)
mux["/foo"]=fooHandler
func fooHandler(w,r){
}
再定義一個Handler作為默認的handler,實現路由
type myHandler struct{}
func (*myHandler)ServeHTTP(w,r){
if h,ok:=mux[r.URL.String()];ok{ //注意mux[]的匹配。需要的時候,要用path包,比如我就用到了mux[path.Dir(r.URL.path)]。
h(w,r)
return
}
}
server自己定義:
server:=http.Server{
Addr: ":9090",
Handler: &myhandler{}, //myhandler在這里使用
ReadTimeout: 5 * time.Second,
}
3、簡單文件服務器實現的三種方法
(1)
1 package main 2 3 import ( 4 "fmt" 5 "log" 6 "net/http" 7 ) 8 9 func sayHello(w http.ResponseWriter, r *http.Request) { 10 fmt.Fprintf(w, "%v", "Hello,this is from FileServer1.") //輸出到客戶端 11 } 12 func main() { 13 http.HandleFunc("/", sayHello) 14 err := http.ListenAndServe(":9090", nil) //使用默認handler = DefaultServeMux 15 if err != nil { 16 log.Fatal("ListenAndServe: ", err) 17 } 18 }
(2)
1 package main 2 3 import ( 4 "fmt" 5 "log" 6 "net/http" 7 ) 8 9 type myhandler struct { 10 } 11 12 func sayHello(w http.ResponseWriter, r *http.Request) { 13 fmt.Fprintf(w, "%v", "Hello,this is from FileServer2.") 14 } 15 func (*myhandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 16 fmt.Fprintf(w, "%v", "Bye,this is from FileServer2.") 17 } 18 19 func main() { 20 mux := http.NewServeMux() 21 mux.Handle("/b", &myhandler{}) 22 mux.HandleFunc("/", sayHello) 23 err := http.ListenAndServe(":9090", mux) 24 if err != nil { 25 log.Fatal("ListenAndServe: ", err) 26 } 27 }
(3)
1 package main 2 3 import ( 4 "fmt" 5 "log" 6 "net/http" 7 "time" 8 ) 9 10 type myhandler struct { 11 } 12 13 var mux map[string]func(http.ResponseWriter, *http.Request) 14 15 func sayHello(w http.ResponseWriter, r *http.Request) { 16 fmt.Fprintf(w, "%v", "Hello,this is from FileServer3.") 17 } 18 func (*myhandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 19 if h, ok := mux[r.URL.String()]; ok { 20 h(w, r) 21 return 22 } 23 } 24 25 func main() { 26 server := http.Server{ 27 Addr: ":9090", 28 Handler: &myhandler{}, 29 ReadTimeout: 5 * time.Second, 30 } 31 mux = make(map[string]func(http.ResponseWriter, *http.Request)) 32 mux["/"] = sayHello 33 err := server.ListenAndServe() 34 if err != nil { 35 log.Fatal("ListenAndServe: ", err) 36 } 37 }
