f7e7fab6 by astaxie

support autorouter

1 parent fbde7df4
...@@ -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 {
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!