support user define function
+//Add("/user",&UserController{})
+//Add("/api/list",&RestController{},"*:ListFood")
+//Add("/api/create",&RestController{},"post:CreateFood")
+//Add("/api/update",&RestController{},"put:UpdateFood")
+//Add("/api/delete",&RestController{},"delete:DeleteFood")
+//Add("/api",&RestController{},"get,post:ApiFunc")
+//Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc")
Showing
2 changed files
with
85 additions
and
15 deletions
| ... | @@ -13,11 +13,14 @@ import ( | ... | @@ -13,11 +13,14 @@ import ( |
| 13 | "strings" | 13 | "strings" |
| 14 | ) | 14 | ) |
| 15 | 15 | ||
| 16 | var HTTPMETHOD = []string{"get", "post", "put", "delete", "patch", "options", "head"} | ||
| 17 | |||
| 16 | type controllerInfo struct { | 18 | type controllerInfo struct { |
| 17 | pattern string | 19 | pattern string |
| 18 | regex *regexp.Regexp | 20 | regex *regexp.Regexp |
| 19 | params map[int]string | 21 | params map[int]string |
| 20 | controllerType reflect.Type | 22 | controllerType reflect.Type |
| 23 | methods map[string]string | ||
| 21 | } | 24 | } |
| 22 | 25 | ||
| 23 | type userHandler struct { | 26 | type userHandler struct { |
| ... | @@ -38,7 +41,16 @@ func NewControllerRegistor() *ControllerRegistor { | ... | @@ -38,7 +41,16 @@ func NewControllerRegistor() *ControllerRegistor { |
| 38 | return &ControllerRegistor{routers: make([]*controllerInfo, 0), userHandlers: make(map[string]*userHandler)} | 41 | return &ControllerRegistor{routers: make([]*controllerInfo, 0), userHandlers: make(map[string]*userHandler)} |
| 39 | } | 42 | } |
| 40 | 43 | ||
| 41 | func (p *ControllerRegistor) Add(pattern string, c ControllerInterface) { | 44 | //methods support like this: |
| 45 | //default methods is the same name as method | ||
| 46 | //Add("/user",&UserController{}) | ||
| 47 | //Add("/api/list",&RestController{},"*:ListFood") | ||
| 48 | //Add("/api/create",&RestController{},"post:CreateFood") | ||
| 49 | //Add("/api/update",&RestController{},"put:UpdateFood") | ||
| 50 | //Add("/api/delete",&RestController{},"delete:DeleteFood") | ||
| 51 | //Add("/api",&RestController{},"get,post:ApiFunc") | ||
| 52 | //Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc") | ||
| 53 | func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingMethods ...string) { | ||
| 42 | parts := strings.Split(pattern, "/") | 54 | parts := strings.Split(pattern, "/") |
| 43 | 55 | ||
| 44 | j := 0 | 56 | j := 0 |
| ... | @@ -82,13 +94,35 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface) { | ... | @@ -82,13 +94,35 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface) { |
| 82 | } | 94 | } |
| 83 | } | 95 | } |
| 84 | } | 96 | } |
| 97 | t := reflect.Indirect(reflect.ValueOf(c)).Type() | ||
| 98 | methods := make(map[string]string) | ||
| 99 | if len(mappingMethods) > 0 { | ||
| 100 | semi := strings.Split(mappingMethods[0], ";") | ||
| 101 | for _, v := range semi { | ||
| 102 | colon := strings.Split(v, ":") | ||
| 103 | if len(colon) != 2 { | ||
| 104 | panic("method mapping fomate is error") | ||
| 105 | } | ||
| 106 | comma := strings.Split(colon[0], ",") | ||
| 107 | for _, m := range comma { | ||
| 108 | if m == "*" || inSlice(strings.ToLower(m), HTTPMETHOD) { | ||
| 109 | if _, ok := t.MethodByName(colon[1]); ok { | ||
| 110 | methods[strings.ToLower(m)] = colon[1] | ||
| 111 | } else { | ||
| 112 | panic(colon[1] + " method don't exist in the controller " + t.Name()) | ||
| 113 | } | ||
| 114 | } else { | ||
| 115 | panic(v + " is an error method mapping,Don't exist method named " + m) | ||
| 116 | } | ||
| 117 | } | ||
| 118 | } | ||
| 119 | } | ||
| 85 | if j == 0 { | 120 | if j == 0 { |
| 86 | //now create the Route | 121 | //now create the Route |
| 87 | t := reflect.Indirect(reflect.ValueOf(c)).Type() | ||
| 88 | route := &controllerInfo{} | 122 | route := &controllerInfo{} |
| 89 | route.pattern = pattern | 123 | route.pattern = pattern |
| 90 | route.controllerType = t | 124 | route.controllerType = t |
| 91 | 125 | route.methods = methods | |
| 92 | p.fixrouters = append(p.fixrouters, route) | 126 | p.fixrouters = append(p.fixrouters, route) |
| 93 | } else { // add regexp routers | 127 | } else { // add regexp routers |
| 94 | //recreate the url pattern, with parameters replaced | 128 | //recreate the url pattern, with parameters replaced |
| ... | @@ -102,11 +136,12 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface) { | ... | @@ -102,11 +136,12 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface) { |
| 102 | } | 136 | } |
| 103 | 137 | ||
| 104 | //now create the Route | 138 | //now create the Route |
| 105 | t := reflect.Indirect(reflect.ValueOf(c)).Type() | 139 | |
| 106 | route := &controllerInfo{} | 140 | route := &controllerInfo{} |
| 107 | route.regex = regex | 141 | route.regex = regex |
| 108 | route.params = params | 142 | route.params = params |
| 109 | route.pattern = pattern | 143 | route.pattern = pattern |
| 144 | route.methods = methods | ||
| 110 | route.controllerType = t | 145 | route.controllerType = t |
| 111 | p.routers = append(p.routers, route) | 146 | p.routers = append(p.routers, route) |
| 112 | } | 147 | } |
| ... | @@ -397,25 +432,53 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -397,25 +432,53 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 397 | //if response has written,yes don't run next | 432 | //if response has written,yes don't run next |
| 398 | if !w.started { | 433 | if !w.started { |
| 399 | if r.Method == "GET" { | 434 | if r.Method == "GET" { |
| 400 | method = vc.MethodByName("Get") | 435 | if m, ok := runrouter.methods["get"]; ok { |
| 436 | method = vc.MethodByName(m) | ||
| 437 | } else { | ||
| 438 | method = vc.MethodByName("Get") | ||
| 439 | } | ||
| 401 | method.Call(in) | 440 | method.Call(in) |
| 402 | } else if r.Method == "HEAD" { | 441 | } else if r.Method == "HEAD" { |
| 403 | method = vc.MethodByName("Head") | 442 | if m, ok := runrouter.methods["head"]; ok { |
| 443 | method = vc.MethodByName(m) | ||
| 444 | } else { | ||
| 445 | method = vc.MethodByName("Head") | ||
| 446 | } | ||
| 404 | method.Call(in) | 447 | method.Call(in) |
| 405 | } else if r.Method == "DELETE" || (r.Method == "POST" && r.Form.Get("_method") == "delete") { | 448 | } else if r.Method == "DELETE" || (r.Method == "POST" && r.Form.Get("_method") == "delete") { |
| 406 | method = vc.MethodByName("Delete") | 449 | if m, ok := runrouter.methods["delete"]; ok { |
| 450 | method = vc.MethodByName(m) | ||
| 451 | } else { | ||
| 452 | method = vc.MethodByName("Delete") | ||
| 453 | } | ||
| 407 | method.Call(in) | 454 | method.Call(in) |
| 408 | } else if r.Method == "PUT" || (r.Method == "POST" && r.Form.Get("_method") == "put") { | 455 | } else if r.Method == "PUT" || (r.Method == "POST" && r.Form.Get("_method") == "put") { |
| 409 | method = vc.MethodByName("Put") | 456 | if m, ok := runrouter.methods["put"]; ok { |
| 457 | method = vc.MethodByName(m) | ||
| 458 | } else { | ||
| 459 | method = vc.MethodByName("Put") | ||
| 460 | } | ||
| 410 | method.Call(in) | 461 | method.Call(in) |
| 411 | } else if r.Method == "POST" { | 462 | } else if r.Method == "POST" { |
| 412 | method = vc.MethodByName("Post") | 463 | if m, ok := runrouter.methods["post"]; ok { |
| 464 | method = vc.MethodByName(m) | ||
| 465 | } else { | ||
| 466 | method = vc.MethodByName("Post") | ||
| 467 | } | ||
| 413 | method.Call(in) | 468 | method.Call(in) |
| 414 | } else if r.Method == "PATCH" { | 469 | } else if r.Method == "PATCH" { |
| 415 | method = vc.MethodByName("Patch") | 470 | if m, ok := runrouter.methods["patch"]; ok { |
| 471 | method = vc.MethodByName(m) | ||
| 472 | } else { | ||
| 473 | method = vc.MethodByName("Patch") | ||
| 474 | } | ||
| 416 | method.Call(in) | 475 | method.Call(in) |
| 417 | } else if r.Method == "OPTIONS" { | 476 | } else if r.Method == "OPTIONS" { |
| 418 | method = vc.MethodByName("Options") | 477 | if m, ok := runrouter.methods["options"]; ok { |
| 478 | method = vc.MethodByName(m) | ||
| 479 | } else { | ||
| 480 | method = vc.MethodByName("Options") | ||
| 481 | } | ||
| 419 | method.Call(in) | 482 | method.Call(in) |
| 420 | } | 483 | } |
| 421 | gotofunc := vc.Elem().FieldByName("gotofunc").String() | 484 | gotofunc := vc.Elem().FieldByName("gotofunc").String() |
| ... | @@ -432,10 +495,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -432,10 +495,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 432 | method = vc.MethodByName("Render") | 495 | method = vc.MethodByName("Render") |
| 433 | method.Call(in) | 496 | method.Call(in) |
| 434 | } | 497 | } |
| 435 | if !w.started { | 498 | method = vc.MethodByName("Finish") |
| 436 | method = vc.MethodByName("Finish") | 499 | method.Call(in) |
| 437 | method.Call(in) | ||
| 438 | } | ||
| 439 | } | 500 | } |
| 440 | } | 501 | } |
| 441 | method = vc.MethodByName("Destructor") | 502 | method = vc.MethodByName("Destructor") | ... | ... |
| ... | @@ -170,3 +170,12 @@ func Htmlunquote(src string) string { | ... | @@ -170,3 +170,12 @@ func Htmlunquote(src string) string { |
| 170 | 170 | ||
| 171 | return strings.TrimSpace(text) | 171 | return strings.TrimSpace(text) |
| 172 | } | 172 | } |
| 173 | |||
| 174 | func inSlice(v string, sl []string) bool { | ||
| 175 | for _, vv := range sl { | ||
| 176 | if vv == v { | ||
| 177 | return true | ||
| 178 | } | ||
| 179 | } | ||
| 180 | return false | ||
| 181 | } | ... | ... |
-
Please register or sign in to post a comment