mirror of
https://gitee.com/johng/gf.git
synced 2024-12-02 20:28:17 +08:00
调整BindControllerMethod及BindObjectMethod逻辑为绑定路由到指定的方法执行
This commit is contained in:
parent
2337b86815
commit
21a758b3a2
@ -15,9 +15,14 @@ import (
|
||||
|
||||
// 绑定控制器,控制器需要实现gmvc.Controller接口
|
||||
// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话
|
||||
// 第三个参数methods用以指定需要注册的方法,支持多个方法名称,多个方法以英文“,”号分隔,区分大小写
|
||||
func (s *Server)BindController(pattern string, c Controller, methods...string) error {
|
||||
methodMap := (map[string]bool)(nil)
|
||||
if len(methods) > 0 {
|
||||
return s.BindControllerMethod(pattern, c, strings.Join(methods, ","))
|
||||
methodMap = make(map[string]bool)
|
||||
for _, v := range strings.Split(methods[0], ",") {
|
||||
methodMap[strings.TrimSpace(v)] = true
|
||||
}
|
||||
}
|
||||
// 遍历控制器,获取方法列表,并构造成uri
|
||||
m := make(handlerMap)
|
||||
@ -26,10 +31,13 @@ func (s *Server)BindController(pattern string, c Controller, methods...string) e
|
||||
sname := t.Elem().Name()
|
||||
for i := 0; i < v.NumMethod(); i++ {
|
||||
mname := t.Method(i).Name
|
||||
if methodMap != nil && !methodMap[mname] {
|
||||
continue
|
||||
}
|
||||
if mname == "Init" || mname == "Shut" || mname == "Exit" {
|
||||
continue
|
||||
}
|
||||
key := s.mergeBuildInNameToPattern(pattern, sname, mname)
|
||||
key := s.mergeBuildInNameToPattern(pattern, sname, mname, true)
|
||||
m[key] = &handlerItem {
|
||||
ctype : v.Elem().Type(),
|
||||
fname : mname,
|
||||
@ -54,41 +62,39 @@ func (s *Server)BindController(pattern string, c Controller, methods...string) e
|
||||
return s.bindHandlerByMap(m)
|
||||
}
|
||||
|
||||
// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话
|
||||
// 第三个参数methods支持多个方法注册,多个方法以英文“,”号分隔,不区分大小写
|
||||
func (s *Server)BindControllerMethod(pattern string, c Controller, methods string) error {
|
||||
// 绑定路由到指定的方法执行
|
||||
func (s *Server)BindControllerMethod(pattern string, c Controller, method string) error {
|
||||
m := make(handlerMap)
|
||||
v := reflect.ValueOf(c)
|
||||
e := v.Type().Elem()
|
||||
t := v.Elem().Type()
|
||||
sname := e.Name()
|
||||
for _, method := range strings.Split(methods, ",") {
|
||||
mname := strings.TrimSpace(method)
|
||||
if !v.MethodByName(mname).IsValid() {
|
||||
return errors.New("invalid method name:" + mname)
|
||||
mname := strings.TrimSpace(method)
|
||||
if !v.MethodByName(mname).IsValid() {
|
||||
return errors.New("invalid method name:" + mname)
|
||||
}
|
||||
key := s.mergeBuildInNameToPattern(pattern, sname, mname, false)
|
||||
m[key] = &handlerItem {
|
||||
ctype : t,
|
||||
fname : mname,
|
||||
faddr : nil,
|
||||
}
|
||||
// 如果方法中带有Index方法,那么额外自动增加一个路由规则匹配主URI
|
||||
if strings.EqualFold(mname, "Index") {
|
||||
p := key
|
||||
if strings.EqualFold(p[len(p) - 6:], "/index") {
|
||||
p = p[0 : len(p) - 6]
|
||||
if len(p) == 0 {
|
||||
p = "/"
|
||||
}
|
||||
}
|
||||
key := s.mergeBuildInNameToPattern(pattern, sname, mname)
|
||||
m[key] = &handlerItem {
|
||||
m[p] = &handlerItem {
|
||||
ctype : t,
|
||||
fname : mname,
|
||||
faddr : nil,
|
||||
}
|
||||
// 如果方法中带有Index方法,那么额外自动增加一个路由规则匹配主URI
|
||||
if strings.EqualFold(mname, "Index") {
|
||||
p := key
|
||||
if strings.EqualFold(p[len(p) - 6:], "/index") {
|
||||
p = p[0 : len(p) - 6]
|
||||
if len(p) == 0 {
|
||||
p = "/"
|
||||
}
|
||||
}
|
||||
m[p] = &handlerItem {
|
||||
ctype : t,
|
||||
fname : mname,
|
||||
faddr : nil,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s.bindHandlerByMap(m)
|
||||
}
|
||||
|
||||
|
@ -47,13 +47,17 @@ func (s *Server) bindHandlerByMap(m handlerMap) error {
|
||||
// 规则1:pattern中的URI包含{.struct}关键字,则替换该关键字为结构体名称;
|
||||
// 规则1:pattern中的URI包含{.method}关键字,则替换该关键字为方法名称;
|
||||
// 规则2:如果不满足规则1,那么直接将防发明附加到pattern中的URI后面;
|
||||
func (s *Server) mergeBuildInNameToPattern(pattern string, structName, methodName string) string {
|
||||
func (s *Server) mergeBuildInNameToPattern(pattern string, structName, methodName string, allowAppend bool) string {
|
||||
structName = s.nameToUrlPart(structName)
|
||||
methodName = s.nameToUrlPart(methodName)
|
||||
pattern = strings.Replace(pattern, "{.struct}", structName, -1)
|
||||
if strings.Index(pattern, "{.method}") != -1 {
|
||||
return strings.Replace(pattern, "{.method}", methodName, -1)
|
||||
}
|
||||
// 不允许将方法名称append到路由末尾
|
||||
if !allowAppend {
|
||||
return pattern
|
||||
}
|
||||
// 检测域名后缀
|
||||
array := strings.Split(pattern, "@")
|
||||
// 分离URI(其实可能包含HTTP Method)
|
||||
|
@ -14,25 +14,32 @@ import (
|
||||
)
|
||||
|
||||
// 绑定对象到URI请求处理中,会自动识别方法名称,并附加到对应的URI地址后面
|
||||
// 需要注意对象方法的定义必须按照ghttp.HandlerFunc来定义
|
||||
// 第三个参数methods用以指定需要注册的方法,支持多个方法名称,多个方法以英文“,”号分隔,区分大小写
|
||||
func (s *Server)BindObject(pattern string, obj interface{}, methods...string) error {
|
||||
methodMap := (map[string]bool)(nil)
|
||||
if len(methods) > 0 {
|
||||
return s.BindObjectMethod(pattern, obj, strings.Join(methods, ","))
|
||||
methodMap = make(map[string]bool)
|
||||
for _, v := range strings.Split(methods[0], ",") {
|
||||
methodMap[strings.TrimSpace(v)] = true
|
||||
}
|
||||
}
|
||||
m := make(handlerMap)
|
||||
v := reflect.ValueOf(obj)
|
||||
t := v.Type()
|
||||
sname := t.Elem().Name()
|
||||
for i := 0; i < v.NumMethod(); i++ {
|
||||
method := t.Method(i).Name
|
||||
key := s.mergeBuildInNameToPattern(pattern, sname, method)
|
||||
mname := t.Method(i).Name
|
||||
if methodMap != nil && !methodMap[mname] {
|
||||
continue
|
||||
}
|
||||
key := s.mergeBuildInNameToPattern(pattern, sname, mname, true)
|
||||
m[key] = &handlerItem {
|
||||
ctype : nil,
|
||||
fname : "",
|
||||
faddr : v.Method(i).Interface().(func(*Request)),
|
||||
}
|
||||
// 如果方法中带有Index方法,那么额外自动增加一个路由规则匹配主URI
|
||||
if strings.EqualFold(method, "Index") {
|
||||
if strings.EqualFold(mname, "Index") {
|
||||
p := key
|
||||
if strings.EqualFold(p[len(p) - 6:], "/index") {
|
||||
p = p[0 : len(p) - 6]
|
||||
@ -52,39 +59,38 @@ func (s *Server)BindObject(pattern string, obj interface{}, methods...string) er
|
||||
|
||||
// 绑定对象到URI请求处理中,会自动识别方法名称,并附加到对应的URI地址后面
|
||||
// 第三个参数methods支持多个方法注册,多个方法以英文“,”号分隔,区分大小写
|
||||
func (s *Server)BindObjectMethod(pattern string, obj interface{}, methods string) error {
|
||||
func (s *Server)BindObjectMethod(pattern string, obj interface{}, method string) error {
|
||||
m := make(handlerMap)
|
||||
v := reflect.ValueOf(obj)
|
||||
t := v.Type()
|
||||
sname := t.Elem().Name()
|
||||
for _, method := range strings.Split(methods, ",") {
|
||||
mname := strings.TrimSpace(method)
|
||||
fval := v.MethodByName(mname)
|
||||
if !fval.IsValid() {
|
||||
return errors.New("invalid method name:" + mname)
|
||||
mname := strings.TrimSpace(method)
|
||||
fval := v.MethodByName(mname)
|
||||
if !fval.IsValid() {
|
||||
return errors.New("invalid method name:" + mname)
|
||||
}
|
||||
key := s.mergeBuildInNameToPattern(pattern, sname, mname, false)
|
||||
m[key] = &handlerItem{
|
||||
ctype : nil,
|
||||
fname : "",
|
||||
faddr : fval.Interface().(func(*Request)),
|
||||
}
|
||||
// 如果方法中带有Index方法,那么额外自动增加一个路由规则匹配主URI
|
||||
if strings.EqualFold(mname, "Index") {
|
||||
p := key
|
||||
if strings.EqualFold(p[len(p) - 6:], "/index") {
|
||||
p = p[0 : len(p) - 6]
|
||||
if len(p) == 0 {
|
||||
p = "/"
|
||||
}
|
||||
}
|
||||
key := s.mergeBuildInNameToPattern(pattern, sname, mname)
|
||||
m[key] = &handlerItem{
|
||||
m[p] = &handlerItem {
|
||||
ctype : nil,
|
||||
fname : "",
|
||||
faddr : fval.Interface().(func(*Request)),
|
||||
}
|
||||
// 如果方法中带有Index方法,那么额外自动增加一个路由规则匹配主URI
|
||||
if strings.EqualFold(mname, "Index") {
|
||||
p := key
|
||||
if strings.EqualFold(p[len(p) - 6:], "/index") {
|
||||
p = p[0 : len(p) - 6]
|
||||
if len(p) == 0 {
|
||||
p = "/"
|
||||
}
|
||||
}
|
||||
m[p] = &handlerItem {
|
||||
ctype : nil,
|
||||
fname : "",
|
||||
faddr : fval.Interface().(func(*Request)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s.bindHandlerByMap(m)
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,11 @@ type Method struct {
|
||||
}
|
||||
|
||||
func init() {
|
||||
g.Server().BindControllerMethod("/method", &Method{}, "Name, Age")
|
||||
// 第三个参数指定主要注册的方法,其他方法不注册,方法名称会自动追加到给定路由后面,构成新路由
|
||||
// 以下注册会中注册两个新路由: /method/name, /method/age
|
||||
g.Server().BindController("/method", new(Method), "Name, Age")
|
||||
// 绑定路由到指定的方法执行,以下注册只会注册一个路由: /method-name
|
||||
g.Server().BindControllerMethod("/method-name", new(Method), "Name")
|
||||
}
|
||||
|
||||
func (c *Method) Name() {
|
||||
|
@ -9,8 +9,9 @@ type ObjectMethod struct {}
|
||||
|
||||
func init() {
|
||||
obj := &ObjectMethod{}
|
||||
g.Server().BindObjectMethod("/object-method", obj, "Show1, Show2, Show3")
|
||||
g.Server().Domain("localhost").BindObjectMethod("/object-method", obj, "Show4")
|
||||
g.Server().BindObject("/object-method", obj, "Show1, Show2, Show3")
|
||||
g.Server().BindObjectMethod("/object-method-show1", obj, "Show1")
|
||||
g.Server().Domain("localhost").BindObject("/object-method", obj, "Show4")
|
||||
}
|
||||
|
||||
func (o *ObjectMethod) Show1(r *ghttp.Request) {
|
||||
|
@ -2,12 +2,10 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"os"
|
||||
)
|
||||
|
||||
|
||||
|
||||
func main() {
|
||||
fmt.Println(filepath.Abs(filepath.Dir(os.Args[0])))
|
||||
methodMap := make(map[string]bool)
|
||||
methodMap["t"] = true
|
||||
fmt.Println(methodMap["t"])
|
||||
}
|
Loading…
Reference in New Issue
Block a user