finish router get example

This commit is contained in:
Jason li 2021-01-06 12:51:54 +08:00
parent 9b3a79772b
commit 07d0dccd89
2 changed files with 109 additions and 1 deletions

View File

@ -20,6 +20,7 @@ import (
"net/http"
"path"
"reflect"
"runtime"
"strconv"
"strings"
"sync"
@ -332,6 +333,93 @@ func (p *ControllerRegister) GiveBackContext(ctx *beecontext.Context) {
p.pool.Put(ctx)
}
// RouterGet add post method
// usage:
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// RouterGet("/api/:id", MyController.Ping)
func (p *ControllerRegister) RouterGet(pattern string, f interface{}) {
p.AddRouterMethod(http.MethodGet, pattern, f)
}
// AddRouterMethod add http method router
// usage:
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// AddRouterMethod("get","/api/:id", MyController.Ping)
func (p *ControllerRegister) AddRouterMethod(method, pattern string, f interface{}) {
method = strings.ToUpper(method)
if method != "*" && !HTTPMETHOD[method] {
panic("not support http method: " + method)
}
ct, methodName := getReflectTypeAndMethod(f)
route := &ControllerInfo{}
route.pattern = pattern
route.routerType = routerTypeBeego
route.sessionOn = p.cfg.WebConfig.Session.SessionOn
route.controllerType = ct
route.methods = map[string]string{method: methodName}
p.addToRouter(method, pattern, route)
}
// get reflect controller type and method by controller method expression
func getReflectTypeAndMethod(f interface{}) (controllerType reflect.Type, method string) {
// check f is a function
funcType := reflect.TypeOf(f)
if funcType.Kind() != reflect.Func {
panic("not a method")
}
// get function name
funcObj := runtime.FuncForPC(reflect.ValueOf(f).Pointer())
if funcObj == nil {
panic("cannot find the method")
}
funcNameSli := strings.Split(funcObj.Name(), ".")
lFuncSli := len(funcNameSli)
if lFuncSli == 0 {
panic("invalid method full name: " + funcObj.Name())
}
method = funcNameSli[lFuncSli-1]
if len(method) == 0 {
panic("method name is empty")
} else if method[0] > 96 || method[0] < 65 {
panic("not a public method")
}
// check only one param which is the method receiver
if numIn := funcType.NumIn(); numIn != 1 {
panic("invalid number of param in")
}
// check the receiver implement ControllerInterface
controllerType = funcType.In(0)
_, ok := reflect.New(controllerType).Interface().(ControllerInterface)
if !ok {
panic(controllerType.String() + " is not implemented ControllerInterface")
}
// check controller has the method
_, exists := controllerType.MethodByName(method)
if !exists {
panic(controllerType.String() + " has no method " + method)
}
return
}
// Get add get method
// usage:
// Get("/", func(ctx *context.Context){

View File

@ -461,6 +461,26 @@ func (app *HttpServer) AutoPrefix(prefix string, c ControllerInterface) *HttpSer
return app
}
// RouterGet see HttpServer.RouterGet
func RouterGet(rootpath string, f interface{}) {
BeeApp.RouterGet(rootpath, f)
}
// RouterGet used to register router for RouterGet method
// usage:
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// RouterGet("/api/:id", MyController.Ping)
func (app *HttpServer) RouterGet(rootpath string, f interface{}) *HttpServer {
app.Handlers.RouterGet(rootpath, f)
return app
}
// Get see HttpServer.Get
func Get(rootpath string, f FilterFunc) *HttpServer {
return BeeApp.Get(rootpath, f)