一、注册 /
根请求转到rootHandle,在rootHandle中为不同的url查找对应的处理接口并执行。
1、tars业务端配置restful url与处理函数,指定url与对应的处理函数。
type TarsHttpMux struct {
http.ServeMux
cfg *TarsHttpConf
}
mux := &tars.TarsHttpMux{}
mux.HandleFunc("/", model.RootHandler)
2、这种方法在注册时把所有的url请求转到rootHandle中进行处理,在业务端rootHandle要实现为不同的url转到不同的接口进行处理的逻辑。rootHandle包含以下逻辑。
var handlers = make(map[string]Handler)
// Handler ...
type Handler interface {
HandleFunc(req string) (interface{}, int, error)
}
//入参handle的接口实现者不同,处理url的逻辑不同
func RegisterHandler(url string, h Handler) error {
_, ok := handlers[url]
if ok {
return errors.New("Url handle func alread registed")
}
handlers[url] = h
return nil
}
RegisterHandler("/test", &test)
func GetHandler(url string) (Handler, error) {
p, ok := handlers[url]
if ok {
return p, nil
}
return nil, errors.New("Get Url handle func failed")
}
GetHandler("test").HandleFunc(req)
3、 mux.HandleFunc("/", model.RootHandler) 调用net/http包的处理函数,注册url与自定义func RootHandler(w http.ResponseWriter, r*http.Request) 处理函数 。
// 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))
}
4、若通过HandleFunc接口注册,需要适配函数类型为Handler接口。即含有ServeHTTP方法。HandlerFunc为一个函数类型,实现了ServeHTTP的方法,是一个Handle接口类型。
// 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 Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
5. 注册url的处理入口函数
// 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
}
}
二、在http/net中为不同的restful-url请求注册不同的接口
1、tars业务端配置restful url与处理函数,指定url与对应的处理函数。
type TarsHttpMux struct {
http.ServeMux
cfg *TarsHttpConf
}
// AdminMux admin http处理对象
var AdminMux *tars.TarsHttpMux = &tars.TarsHttpMux{}
2、业务端定义httphandle结构体,结构体中的成员为接口类型成员,传入结构体接口成员的实现者不同,结构体拥有不同的处理逻辑。 由于 IHandler为httpHandle的匿名类型成员,所以httpHandle结构体可以直接调用HandleFunc接口,即实现了IHandler接口方法,httpHandle结构体也为IHandle接口类型。若想要某一结构体拥有某一接口不同的实现方法时,可以把接口类型作为结构体的一个类型成员。接口成员赋予不同的实现者时,结构体拥有不同的接口实现方法
type httpHandler struct {
IHandler
}
type IHandler interface {
HandleFunc(url string, req []byte) (interface{}, int, error)
}
3、同时业务端httpHandler结构体实现了serverhttp方法,为所有的url通用的处理方法逻辑,不同的处理逻辑在于调用httpHandler.HandleFunc()时。此结构体可为net/http中的Handle接口类型。 不同的url请求对应不同的httpHandle结构体进行处理。
func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//所有的url通用的处理方法逻辑,不同的处理逻辑在于调用httpHandler.HandleFunc()时
}
4、业务端调用RegisterURLHandler接口为不同的url绑定不同的处理接口IHandler,在业务端为所有的url和相应的处理接口,最终执行net/http包中handle接口进行注册。入参Ihandle的接口实现者不同,httpHandle调用的HandleFunc函数逻辑不同,即处理pattern url的逻辑不同。
func RegisterURLHandler(pattern string, handler IHandler) {
h := &httpHandler{handler}
AdminMux.Handle(pattern, h)
}
5、执行net/http包中handle接口,注册url的处理入口函数
// 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
}
}