前言

本文主要介绍了关于golang实现路由调度的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧
项目地址
github (本地下载)
本项目依赖
使用标准库实现,无额外依赖
为什么需要路由调度层
golang http标准库只能精确匹配请求的URI,然后执行handler。现在一般web项目都至少有个Controller层,以struct实现,根据不同的请求路径派发到不同的方法中去。
路由调度器定义
由于golang暂时还不可以动态创建对象(比如java的Class.forName("xxx").newInstance(),xxx是任意存在的class名称)。所以需要手动注册一下controller关系。
由于golang的继承不是一般的OOP,所以也没有父子类这种说法,路由注册那里只能使用interface{}
代码实现
app/app.go
该文件为核心调度文件
package app
import (
"net/http"
"reflect"
"fmt"
)
type application struct {
routes map[string]interface{}
}
func New() *application {
return &application{
routes: make(map[string]interface{}),
}
}
func (p *application) ServeHTTP(w http.ResponseWriter, r *http.Request) {
controllerName := r.URL.Query().Get("c")
actionName := r.URL.Query().Get("a")
if controllerName == "" || actionName == "" {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
route, ok := p.routes[controllerName]
if !ok {
http.Error(w, "Controller Not Found", http.StatusNotFound)
return
}
ele := reflect.ValueOf(route).Elem()
ele.FieldByName("Request").Set(reflect.ValueOf(r))
ele.FieldByName("Response").Set(reflect.ValueOf(w))
ele.MethodByName(actionName).Call([]reflect.Value{})
}
func (p *application) printRoutes() {
for route, controller := range p.routes {
ele := reflect.ValueOf(controller).Type().String()
fmt.Printf("%s %s\n", route, ele)
}
}
func (p *application) Get(route string, controller interface{}) {
p.routes[route] = controller
}
func (p *application) Run(addr string) error {
p.printRoutes()
fmt.Printf("listen on %s\n", addr)
return http.ListenAndServe(addr, p)
}另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。