http 路由实现原理
HTTP 路由组件负责将 HTTP 请求交到对应的函数处理(或者是对应的 struct 的方法),路由在框架中相当于一个事件处理器,而这个事件包括:
- 用户请求的路径(path),参数
- HTTP 请求方法(GET|POST|PUT|DELETE|PATCH)
路由器就是根据用户请求的事件信息转发到相应的处理函数(控制层)
默认的路由实现
func fooHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
}
http.HandleFunc("/foo", fooHandler)
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})
log.Fatal(http.ListenAndServe(":8080", nil))
DefaultServeMux
路由的思想主要集中在两点:
-
添加路由的信息
DefultserveMux.Handle(pattern string, handler Handler)
-
根据用户请求转发要执行的函数
路由信息的添加:
http.Handlehttp.HandleFuncDefultserveMux.Handle(pattern string, handler Handler)map[string]muxEntry
函数处理:
http.DefaultServeMux
for k, v := range mux.m {
if !pathMatch(k, path) {
continue
}
if h == nil || len(k) > n {
n = len(k)
h = v.h
}
}
自定义路由器实现
基于以上的理解,我们可以自定义一个路由处理器:
package main
import (
"fmt"
"net/http"
)
type MyHandle struct {
}
func (handle *MyHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/hello":
sayHello(w,r)
return
case "/hi":
sayHi(w,r)
return
}
http.NotFound(w,r)
return
}
func sayHello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello Golang!")
}
func sayHi(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi Golang!")
}
func main() {
handle := MyHandle{}
http.ListenAndServe(":9000", &handle)
}
go run main.go