前言
本文主要介绍了关于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) }
app/controller.go
控制器"基类"
package app import "net/http" type Controller struct { Response http.ResponseWriter Request *http.Request }
controller/site.go
具体业务逻辑类
package controllers import ( "fmt" "app" ) type SiteController struct { app.Controller } func (p SiteController) Index() { fmt.Fprint(p.Response, p.Request.RequestURI) }
main.go
入口文件
package main import ( _ "github.com/go-sql-driver/mysql" "app" "controllers" ) func main() { application := app.New() application.Get("site", &controllers.SiteController{}) application.Run(":8080") }
运行项目
启动进程
访问http://localhost:8080?c=site&a=Index会输出/?c=site&a=Index
写在最后
希望这个小小的项目能启发到各位读者,早日开发出适合自己的Web框架!
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对小牛知识库的支持。
本文向大家介绍利用Spring Cloud Zuul实现动态路由示例代码,包括了利用Spring Cloud Zuul实现动态路由示例代码的使用技巧和注意事项,需要的朋友参考一下 前言 本文主要给大家介绍了关于Spring Cloud Zuul实现动态路由的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 Zuul 是提供动态路由,监控,弹性,安全等的边缘服务。Zuul
本文向大家介绍AngularJs ng-route路由详解及实例代码,包括了AngularJs ng-route路由详解及实例代码的使用技巧和注意事项,需要的朋友参考一下 前提 首先需要在页面引入angular和angular-route,注意要在angular-route之前引入angular <script src="../../bower_components/angular/angular
本文向大家介绍nodeJS实现路由功能实例代码,包括了nodeJS实现路由功能实例代码的使用技巧和注意事项,需要的朋友参考一下 前面的话 本文将使用NodeJS实现较复杂应用的路由功能 结构 项目结构如下 代码如下 功能 【router.js】 【404.html】 【about.html】 【home.html】 演示 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教
本文向大家介绍AngularJS中的路由使用及实现代码,包括了AngularJS中的路由使用及实现代码的使用技巧和注意事项,需要的朋友参考一下 前 言 本章节将为大家介绍 AngularJS 路由。AngularJS 路由允许我们通过不同的 URL 访问不同的内容。通过 AngularJS 可以实现多视图的单页Web应用(single page web application,SPA)。 1.1
本文向大家介绍golang 40行代码实现通用协程池,包括了golang 40行代码实现通用协程池的使用技巧和注意事项,需要的朋友参考一下 代码仓库 goroutine-pool golang的协程管理 golang协程机制很方便的解决了并发编程的问题,但是协程并不是没有开销的,所以也需要适当限制一下数量。 不使用协程池的代码(示例代码使用chan实现,代码略啰嗦) 需要实现的需求有两个: 限制最
本文向大家介绍利用Golang如何调用Linux命令详解,包括了利用Golang如何调用Linux命令详解的使用技巧和注意事项,需要的朋友参考一下 本文介绍的是Golang使用 os/exec 来执行 Linux 命令,分享出来供大家参考学习,下面来看看详细的介绍: 下面是一个简单的示例: 或者创建一个缓冲读取器按行读取: 输出结果: 在写这句 if err.Error() != "EOF" 时,