加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
router.go 3.25 KB
一键复制 编辑 原始数据 按行查看 历史
package hxgo
import (
"strings"
"path"
"reflect"
)
// router object
type Router struct {
routes []*Route
}
// append route into router
func (this *Router) Append(rt *Route){
this.routes = append(this.routes,rt)
}
// dispatch request with rules in router
func (this *Router) Dispatch(w *Response, r *Request, v *View) bool {
for _, route := range this.routes {
result := route.Call(w, r, v)
if result == true {
return true
}
}
return false
}
// route rule object
type Route struct {
url string
method string
ext string
handler reflect.Type
}
// set route method
func (this *Route) Method(methods string) *Route {
this.method = strings.ToUpper(methods)
return this
}
// set route suffix
func (this *Route) Suffix(sfx string) *Route {
this.ext = strings.ToLower(sfx)
return this
}
// check route is matched
func (this *Route) is(url string, method string) bool {
if !strings.HasPrefix(url, this.url) {
return false
}
if this.method != "ALL" {
if !strings.Contains(this.method, method) {
return false
}
}
if this.ext != "" {
ext := path.Ext(url)
if !strings.Contains(this.ext, ext) {
return false
}
}
return true
}
// get url param
func (this *Route) getParam(url string) []string {
ext := path.Ext(url)
if ext != "" {
url = strings.Replace(url, ext, "", -1)
}
url = strings.Replace(url, this.url, "", 1)
tmp := strings.Split(url, "/")
var param []string
for _, t := range tmp {
if len(t) > 0 {
param = append(param, t)
}
}
return param
}
// get calls from param
func (this *Route) getCalls(param []string, method string) []string {
calls := make([]string, 0)
if len(param) >= 2 && param[1] != "" {
calls = append(calls, strings.Title(param[0]) + strings.Title(param[1]) + method)
}
if len(param) >= 1 && param[0] != "" {
calls = append(calls, strings.Title(param[0]) + method)
}
calls = append(calls, "Index" + method)
calls = append(calls, "Index")
return calls
}
// call route method
func (this *Route) Call(w *Response, r *Request, v *View) bool {
if !this.is(r.Url, r.Method) {
return false
}
param := this.getParam(r.Url)
calls := this.getCalls(param, r.Method)
r.Param = param
rType := this.handler
if rType == nil {
return false
}
rValue := reflect.New(rType)
// do init
rInit := rValue.MethodByName("New")
initArgs := make([]reflect.Value, 3)
initArgs[0] = reflect.ValueOf(w)
initArgs[1] = reflect.ValueOf(r)
initArgs[2] = reflect.ValueOf(v)
rInit.Call(initArgs)
rInit2 := rValue.MethodByName("Init")
init2Args := make([]reflect.Value, 0)
rInit2.Call(init2Args)
if w.IsDone {
return true
}
for _, call := range calls {
rMethod := rValue.MethodByName(call)
if !rMethod.IsValid() {
continue
}
// do called method
args := make([]reflect.Value, 0)
rMethod.Call(args)
break
}
return true
}
// define route rule handler interface
type RouteHandler interface {
New(w *Response, r *Request, v *View)
Init()
Index()
}
//-------------------
// create new router
func NewRouter() *Router {
r := &Router{}
r.routes = make([]*Route, 0)
return r
}
// create route rule
func NewRoute(url string, handler RouteHandler) *Route {
r := &Route{}
r.url = url
r.method = "ALL"
if handler != nil {
r.handler = reflect.Indirect(reflect.ValueOf(handler)).Type()
}
return r
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化