本文首先介绍使用http标准库搭建web服务,共三种方式,然后简析内部实现原理,最后对http的使用做出总结。阅读本文需要简单的go基础知识和web开发相关知识。

1.使用http搭建简单的web服务

1.1 单个handler形式

func main() {
	server := http.Server{
    	Addr:    "127.0.0.1:8081",
    	Handler: &helloHandler{},
	}
	_ = server.ListenAndServe()
}
type helloHandler struct{}

func (h *helloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	_, _ = fmt.Fprintf(w, "hello World")
}
复制代码
8081HandlerhelloHandlerServeHTTPlocalhost:8081localhost:8081/alocalhost:8081/a/ahello World

1.2 多个handler

func main() {
	server2 := http.Server{
    	Addr: "127.0.0.1:8082",
	}
	http.Handle("/hello", &helloHandler{})
	http.Handle("/hi", &hiHandler{})
	_ = server2.ListenAndServe()
}

type helloHandler struct{}
func (h *helloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	_, _ = fmt.Fprintf(w, "hello World")
}

type hiHandler struct{}
func (h *hiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	_, _ = fmt.Fprintf(w, "hi World")
}
复制代码
8082/hello/hihelloHandlerhiHandlerServeHTTPServerHandlerDefaultServeMuxHandlerHandler
    mux := http.NewServeMux()
	mux.Handle("/hello", &helloHandler{})
	mux.Handle("/hi", &hiHandler{})
	
	server2 := http.Server{
    	Addr: "127.0.0.1:8082",
    	Handler:mux,
	}
复制代码

1.3 HandlerFunc

func main() {
	server3 := http.Server{
    	Addr: "127.0.0.1:8083",
	}
	http.HandleFunc("/hello", helloFunc)
	http.HandleFunc("/hi", hiFunc)
	_ = server3.ListenAndServe()

}

func helloFunc(w http.ResponseWriter, r *http.Request)  {
	_, _ = fmt.Fprintf(w, "hello World")
}
func hiFunc(w http.ResponseWriter, r *http.Request)  {
	_, _ = fmt.Fprintf(w, "hi World")
}
复制代码
8083/hello/hihelloFunchiFuncServerHandlerHandler
mux := http.NewServeMux()
mux.HandleFunc("/hello",helloFunc)
mux.HandleFunc("/hi",hiFunc)
	
server3 := http.Server{
    Addr: "127.0.0.1:8083",
	Handler:mux,
}
复制代码

2.http库内部实现简析

http.Server
http.Server
type Server struct {
	Handler Handler // handler to invoke, http.DefaultServeMux if nil
	...
	...
}
复制代码
http.Handler
type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}
复制代码
ServerHandler所有HandlerHandlerServeHTTPHandlerhttphttp.DefaultServeMuxServeMuxServeHTTPhandler
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) //根据请求寻找对应的Handler
	h.ServeHTTP(w, r) //调用我们自己的handler,处理请求
}
复制代码
ServeMuxfunc (mux *ServeMux) Handle(pattern string, handler Handler)func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))mapfunc (mux * ServeMux) ServeHTTP(w ResponseWriter, r *Request)
http.ServeMux
    type ServeMux struct {
	m     map[string]muxEntry //存储路由信息
	...
}
复制代码
HandlerHandlerFunc
HandlerHandlerFunchttp.Handlehttp.HandleFunchttp.Handle("/hello", &helloHandler{})http.HandleFunc("/hello", hiFunc)http.HandlerHandlerServeHTTP(w ResponseWriter, r *Request)HandlerFuncServeHTTP
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    ...
	mux.Handle(pattern, HandlerFunc(handler))//调用HandlerFunc实现类型转换
}
复制代码
HandlerFunc
type HandlerFunc func(ResponseWriter, *Request)

//实现了`http.Handler`
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
	f(w, r)
}
复制代码

3.总结

HandlerServeMuxHandlerFuncHandlerFunc(handler)handlerHandlerFunc

下一节介绍httprouter