support autorouter
Showing
2 changed files
with
81 additions
and
1 deletions
| ... | @@ -138,6 +138,11 @@ func (app *App) Router(path string, c ControllerInterface, mappingMethods ...str | ... | @@ -138,6 +138,11 @@ func (app *App) Router(path string, c ControllerInterface, mappingMethods ...str |
| 138 | return app | 138 | return app |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | func (app *App) AutoRouter(c ControllerInterface) *App { | ||
| 142 | app.Handlers.AddAuto(c) | ||
| 143 | return app | ||
| 144 | } | ||
| 145 | |||
| 141 | func (app *App) Filter(filter http.HandlerFunc) *App { | 146 | func (app *App) Filter(filter http.HandlerFunc) *App { |
| 142 | app.Handlers.Filter(filter) | 147 | app.Handlers.Filter(filter) |
| 143 | return app | 148 | return app |
| ... | @@ -192,6 +197,11 @@ func RESTRouter(rootpath string, c ControllerInterface) *App { | ... | @@ -192,6 +197,11 @@ func RESTRouter(rootpath string, c ControllerInterface) *App { |
| 192 | return BeeApp | 197 | return BeeApp |
| 193 | } | 198 | } |
| 194 | 199 | ||
| 200 | func AutoRouter(c ControllerInterface) *App { | ||
| 201 | BeeApp.AutoRouter(c) | ||
| 202 | return BeeApp | ||
| 203 | } | ||
| 204 | |||
| 195 | func RouterHandler(path string, c http.Handler) *App { | 205 | func RouterHandler(path string, c http.Handler) *App { |
| 196 | BeeApp.Handlers.AddHandler(path, c) | 206 | BeeApp.Handlers.AddHandler(path, c) |
| 197 | return BeeApp | 207 | return BeeApp | ... | ... |
| ... | @@ -10,6 +10,7 @@ import ( | ... | @@ -10,6 +10,7 @@ import ( |
| 10 | "reflect" | 10 | "reflect" |
| 11 | "regexp" | 11 | "regexp" |
| 12 | "runtime" | 12 | "runtime" |
| 13 | "strconv" | ||
| 13 | "strings" | 14 | "strings" |
| 14 | ) | 15 | ) |
| 15 | 16 | ||
| ... | @@ -35,10 +36,15 @@ type ControllerRegistor struct { | ... | @@ -35,10 +36,15 @@ type ControllerRegistor struct { |
| 35 | fixrouters []*controllerInfo | 36 | fixrouters []*controllerInfo |
| 36 | filters []http.HandlerFunc | 37 | filters []http.HandlerFunc |
| 37 | userHandlers map[string]*userHandler | 38 | userHandlers map[string]*userHandler |
| 39 | autoRouter map[string]map[string]reflect.Type //key:controller key:method value:reflect.type | ||
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | func NewControllerRegistor() *ControllerRegistor { | 42 | func NewControllerRegistor() *ControllerRegistor { |
| 41 | return &ControllerRegistor{routers: make([]*controllerInfo, 0), userHandlers: make(map[string]*userHandler)} | 43 | return &ControllerRegistor{ |
| 44 | routers: make([]*controllerInfo, 0), | ||
| 45 | userHandlers: make(map[string]*userHandler), | ||
| 46 | autoRouter: make(map[string]map[string]reflect.Type), | ||
| 47 | } | ||
| 42 | } | 48 | } |
| 43 | 49 | ||
| 44 | //methods support like this: | 50 | //methods support like this: |
| ... | @@ -148,6 +154,21 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM | ... | @@ -148,6 +154,21 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM |
| 148 | } | 154 | } |
| 149 | } | 155 | } |
| 150 | 156 | ||
| 157 | func (p *ControllerRegistor) AddAuto(c ControllerInterface) { | ||
| 158 | reflectVal := reflect.ValueOf(c) | ||
| 159 | rt := reflectVal.Type() | ||
| 160 | ct := reflect.Indirect(reflectVal).Type() | ||
| 161 | firstParam := strings.ToLower(strings.TrimSuffix(ct.Name(), "Controller")) | ||
| 162 | if _, ok := p.autoRouter[firstParam]; ok { | ||
| 163 | return | ||
| 164 | } else { | ||
| 165 | p.autoRouter[firstParam] = make(map[string]reflect.Type) | ||
| 166 | } | ||
| 167 | for i := 0; i < rt.NumMethod(); i++ { | ||
| 168 | p.autoRouter[firstParam][rt.Method(i).Name] = ct | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 151 | func (p *ControllerRegistor) AddHandler(pattern string, c http.Handler) { | 172 | func (p *ControllerRegistor) AddHandler(pattern string, c http.Handler) { |
| 152 | parts := strings.Split(pattern, "/") | 173 | parts := strings.Split(pattern, "/") |
| 153 | 174 | ||
| ... | @@ -518,6 +539,55 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -518,6 +539,55 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 518 | method.Call(in) | 539 | method.Call(in) |
| 519 | } | 540 | } |
| 520 | 541 | ||
| 542 | //start autorouter | ||
| 543 | |||
| 544 | if !findrouter { | ||
| 545 | for cName, methodmap := range p.autoRouter { | ||
| 546 | if strings.HasPrefix(strings.ToLower(requestPath), "/"+cName) { | ||
| 547 | for mName, controllerType := range methodmap { | ||
| 548 | if strings.HasPrefix(strings.ToLower(requestPath), "/"+cName+"/"+strings.ToLower(mName)) { | ||
| 549 | //parse params | ||
| 550 | otherurl := requestPath[len("/"+cName+"/"+strings.ToLower(mName)):] | ||
| 551 | if len(otherurl) > 1 && otherurl[0] != '/' { | ||
| 552 | plist := strings.Split(otherurl, "/") | ||
| 553 | for k, v := range plist { | ||
| 554 | params[strconv.Itoa(k)] = v | ||
| 555 | } | ||
| 556 | } | ||
| 557 | //Invoke the request handler | ||
| 558 | vc := reflect.New(controllerType) | ||
| 559 | |||
| 560 | //call the controller init function | ||
| 561 | init := vc.MethodByName("Init") | ||
| 562 | in := make([]reflect.Value, 2) | ||
| 563 | ct := &Context{ResponseWriter: w, Request: r, Params: params, RequestBody: requestbody} | ||
| 564 | |||
| 565 | in[0] = reflect.ValueOf(ct) | ||
| 566 | in[1] = reflect.ValueOf(controllerType.Name()) | ||
| 567 | init.Call(in) | ||
| 568 | //call prepare function | ||
| 569 | in = make([]reflect.Value, 0) | ||
| 570 | method := vc.MethodByName("Prepare") | ||
| 571 | method.Call(in) | ||
| 572 | method = vc.MethodByName(mName) | ||
| 573 | method.Call(in) | ||
| 574 | if !w.started { | ||
| 575 | if AutoRender { | ||
| 576 | method = vc.MethodByName("Render") | ||
| 577 | method.Call(in) | ||
| 578 | } | ||
| 579 | method = vc.MethodByName("Finish") | ||
| 580 | method.Call(in) | ||
| 581 | } | ||
| 582 | method = vc.MethodByName("Destructor") | ||
| 583 | method.Call(in) | ||
| 584 | // set find | ||
| 585 | findrouter = true | ||
| 586 | } | ||
| 587 | } | ||
| 588 | } | ||
| 589 | } | ||
| 590 | } | ||
| 521 | //if no matches to url, throw a not found exception | 591 | //if no matches to url, throw a not found exception |
| 522 | if !findrouter { | 592 | if !findrouter { |
| 523 | if h, ok := ErrorMaps["404"]; ok { | 593 | if h, ok := ErrorMaps["404"]; ok { | ... | ... |
-
Please register or sign in to post a comment