add url params -> controller's member feature
Showing
1 changed file
with
41 additions
and
20 deletions
| 1 | package beego | 1 | package beego |
| 2 | 2 | ||
| 3 | import ( | 3 | import ( |
| 4 | "errors" | ||
| 5 | "fmt" | 4 | "fmt" |
| 6 | "net/http" | 5 | "net/http" |
| 7 | "net/url" | 6 | "net/url" |
| ... | @@ -12,6 +11,10 @@ import ( | ... | @@ -12,6 +11,10 @@ import ( |
| 12 | "strings" | 11 | "strings" |
| 13 | ) | 12 | ) |
| 14 | 13 | ||
| 14 | var ( | ||
| 15 | sc *Controller = &Controller{} | ||
| 16 | ) | ||
| 17 | |||
| 15 | type controllerInfo struct { | 18 | type controllerInfo struct { |
| 16 | pattern string | 19 | pattern string |
| 17 | regex *regexp.Regexp | 20 | regex *regexp.Regexp |
| ... | @@ -46,7 +49,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface) { | ... | @@ -46,7 +49,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface) { |
| 46 | if strings.HasPrefix(part, ":") { | 49 | if strings.HasPrefix(part, ":") { |
| 47 | expr := "(.+)" | 50 | expr := "(.+)" |
| 48 | //a user may choose to override the defult expression | 51 | //a user may choose to override the defult expression |
| 49 | // similar to expressjs: ‘/user/:id([0-9]+)’ | 52 | // similar to expressjs: ‘/user/:id([0-9]+)’ |
| 50 | if index := strings.Index(part, "("); index != -1 { | 53 | if index := strings.Index(part, "("); index != -1 { |
| 51 | expr = part[index:] | 54 | expr = part[index:] |
| 52 | part = part[:index] | 55 | part = part[:index] |
| ... | @@ -120,7 +123,7 @@ func (p *ControllerRegistor) AddHandler(pattern string, c http.Handler) { | ... | @@ -120,7 +123,7 @@ func (p *ControllerRegistor) AddHandler(pattern string, c http.Handler) { |
| 120 | if strings.HasPrefix(part, ":") { | 123 | if strings.HasPrefix(part, ":") { |
| 121 | expr := "([^/]+)" | 124 | expr := "([^/]+)" |
| 122 | //a user may choose to override the defult expression | 125 | //a user may choose to override the defult expression |
| 123 | // similar to expressjs: ‘/user/:id([0-9]+)’ | 126 | // similar to expressjs: ‘/user/:id([0-9]+)’ |
| 124 | if index := strings.Index(part, "("); index != -1 { | 127 | if index := strings.Index(part, "("); index != -1 { |
| 125 | expr = part[index:] | 128 | expr = part[index:] |
| 126 | part = part[:index] | 129 | part = part[:index] |
| ... | @@ -185,27 +188,40 @@ func (p *ControllerRegistor) FilterPrefixPath(path string, filter http.HandlerFu | ... | @@ -185,27 +188,40 @@ func (p *ControllerRegistor) FilterPrefixPath(path string, filter http.HandlerFu |
| 185 | }) | 188 | }) |
| 186 | } | 189 | } |
| 187 | 190 | ||
| 188 | func structMap(vc reflect.Value, params *map[string]string) error { | 191 | func StructMap(vc reflect.Value, params *url.Values) error { |
| 189 | for k, v := range *params { | 192 | |
| 193 | for k, t := range *params { | ||
| 194 | v := t[0] | ||
| 190 | names := strings.Split(k, ".") | 195 | names := strings.Split(k, ".") |
| 191 | var value reflect.Value = vc | 196 | var value reflect.Value = vc |
| 192 | for i, name := range names { | 197 | for i, name := range names { |
| 193 | if i != len(names)-1 { | 198 | name = strings.Title(name) |
| 194 | if value.Kind() != reflect.Struct { | 199 | if i == 0 { |
| 195 | return errors.New("arg error") | 200 | if reflect.ValueOf(sc).Elem().FieldByName(name).IsValid() { |
| 201 | Trace("Controller's property should not be changed by mapper.") | ||
| 202 | break | ||
| 196 | } | 203 | } |
| 197 | value := value.FieldByName(name) | 204 | } |
| 205 | if value.Kind() != reflect.Struct { | ||
| 206 | Trace(fmt.Sprintf("arg error, value kind is %v", value.Kind())) | ||
| 207 | break | ||
| 208 | } | ||
| 209 | |||
| 210 | if i != len(names)-1 { | ||
| 211 | value = value.FieldByName(name) | ||
| 198 | if !value.IsValid() { | 212 | if !value.IsValid() { |
| 199 | return errors.New("arg error") | 213 | Trace(fmt.Sprintf("(%v value is not valid %v)", name, value)) |
| 214 | break | ||
| 200 | } | 215 | } |
| 201 | } else { | 216 | } else { |
| 202 | tv := value.FieldByName(name) | 217 | tv := value.FieldByName(name) |
| 203 | fmt.Println(name, tv, tv.Kind()) | ||
| 204 | if !tv.IsValid() { | 218 | if !tv.IsValid() { |
| 205 | return errors.New("arg error") | 219 | Trace(fmt.Sprintf("struct %v has no field named %v", value, name)) |
| 220 | break | ||
| 206 | } | 221 | } |
| 207 | if !tv.CanSet() { | 222 | if !tv.CanSet() { |
| 208 | return errors.New("can not set " + name) | 223 | Trace("can not set " + k) |
| 224 | break | ||
| 209 | } | 225 | } |
| 210 | var l interface{} | 226 | var l interface{} |
| 211 | switch k := tv.Kind(); k { | 227 | switch k := tv.Kind(); k { |
| ... | @@ -216,29 +232,33 @@ func structMap(vc reflect.Value, params *map[string]string) error { | ... | @@ -216,29 +232,33 @@ func structMap(vc reflect.Value, params *map[string]string) error { |
| 216 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32: | 232 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32: |
| 217 | x, err := strconv.Atoi(v) | 233 | x, err := strconv.Atoi(v) |
| 218 | if err != nil { | 234 | if err != nil { |
| 219 | return errors.New("arg " + v + " as int: " + err.Error()) | 235 | Trace("arg " + v + " as int: " + err.Error()) |
| 236 | break | ||
| 220 | } | 237 | } |
| 221 | l = x | 238 | l = x |
| 222 | case reflect.Int64: | 239 | case reflect.Int64: |
| 223 | x, err := strconv.ParseInt(v, 10, 64) | 240 | x, err := strconv.ParseInt(v, 10, 64) |
| 224 | if err != nil { | 241 | if err != nil { |
| 225 | return errors.New("arg " + v + " as int: " + err.Error()) | 242 | Trace("arg " + v + " as int: " + err.Error()) |
| 243 | break | ||
| 226 | } | 244 | } |
| 227 | l = x | 245 | l = x |
| 228 | case reflect.Float32, reflect.Float64: | 246 | case reflect.Float32, reflect.Float64: |
| 229 | x, err := strconv.ParseFloat(v, 64) | 247 | x, err := strconv.ParseFloat(v, 64) |
| 230 | if err != nil { | 248 | if err != nil { |
| 231 | return errors.New("arg " + v + " as float64: " + err.Error()) | 249 | Trace("arg " + v + " as float64: " + err.Error()) |
| 250 | break | ||
| 232 | } | 251 | } |
| 233 | l = x | 252 | l = x |
| 234 | case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | 253 | case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: |
| 235 | x, err := strconv.ParseUint(v, 10, 64) | 254 | x, err := strconv.ParseUint(v, 10, 64) |
| 236 | if err != nil { | 255 | if err != nil { |
| 237 | return errors.New("arg " + v + " as int: " + err.Error()) | 256 | Trace("arg " + v + " as int: " + err.Error()) |
| 257 | break | ||
| 238 | } | 258 | } |
| 239 | l = x | 259 | l = x |
| 240 | case reflect.Struct: | 260 | case reflect.Struct: |
| 241 | fmt.Println("can not set an struct") | 261 | Trace("can not set an struct") |
| 242 | } | 262 | } |
| 243 | 263 | ||
| 244 | tv.Set(reflect.ValueOf(l)) | 264 | tv.Set(reflect.ValueOf(l)) |
| ... | @@ -412,13 +432,14 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -412,13 +432,14 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 412 | //Invoke the request handler | 432 | //Invoke the request handler |
| 413 | vc := reflect.New(runrouter.controllerType) | 433 | vc := reflect.New(runrouter.controllerType) |
| 414 | 434 | ||
| 435 | r.ParseForm() | ||
| 436 | StructMap(vc.Elem(), &r.Form) | ||
| 437 | |||
| 415 | //call the controller init function | 438 | //call the controller init function |
| 416 | init := vc.MethodByName("Init") | 439 | init := vc.MethodByName("Init") |
| 417 | in := make([]reflect.Value, 2) | 440 | in := make([]reflect.Value, 2) |
| 418 | ct := &Context{ResponseWriter: w, Request: r, Params: params} | 441 | ct := &Context{ResponseWriter: w, Request: r, Params: params} |
| 419 | 442 | ||
| 420 | structMap(vc.Elem(), ¶ms) | ||
| 421 | |||
| 422 | in[0] = reflect.ValueOf(ct) | 443 | in[0] = reflect.ValueOf(ct) |
| 423 | in[1] = reflect.ValueOf(runrouter.controllerType.Name()) | 444 | in[1] = reflect.ValueOf(runrouter.controllerType.Name()) |
| 424 | init.Call(in) | 445 | init.Call(in) | ... | ... |
-
Please register or sign in to post a comment