diff --git a/g/net/ghttp/http_server_handler.go b/g/net/ghttp/http_server_handler.go index 0dcbc4fc7..03fcbf129 100644 --- a/g/net/ghttp/http_server_handler.go +++ b/g/net/ghttp/http_server_handler.go @@ -30,6 +30,11 @@ func (s *Server)defaultHttpHandle(w http.ResponseWriter, r *http.Request) { // 其次,如果没有对应的自定义处理接口配置,那么走默认的域名处理接口配置; // 最后,如果以上都没有找到处理接口,那么进行文件处理; func (s *Server)handleRequest(w http.ResponseWriter, r *http.Request) { + // 去掉末尾的"/"号 + if r.URL.Path != "/" { + r.URL.Path = strings.TrimRight(r.URL.Path, "/") + } + // 创建请求处理对象 request := newRequest(s, r, w) // 事件 - BeforeServe diff --git a/g/net/ghttp/http_server_router.go b/g/net/ghttp/http_server_router.go index bd8c1627c..fdd400dbc 100644 --- a/g/net/ghttp/http_server_router.go +++ b/g/net/ghttp/http_server_router.go @@ -60,6 +60,10 @@ func (s *Server)parsePattern(pattern string) (domain, method, uri string, err er if uri == "" { err = errors.New("invalid pattern") } + // 去掉末尾的"/"符号,与路由匹配时处理一直 + if uri != "/" { + uri = strings.TrimRight(uri, "/") + } return } @@ -154,14 +158,6 @@ func (s *Server) searchHandler(r *Request) *handlerCacheItem { if item == nil { item = s.searchHandlerDynamic(r) } - // 如果检索不到服务,那么使用默认的"/"服务注册来执行服务 - // "/"静态路由是特殊的路由,当所有服务都找不到时,会交给"/"路由规则的控制器来处理 - if item == nil && r.URL.Path != "/" { - path := r.URL.Path - r.URL.Path = "/" - item = s.searchHandlerStatic(r) - r.URL.Path = path - } return item } diff --git a/g/net/ghttp/http_server_service.go b/g/net/ghttp/http_server_service.go index b5dbb40f7..5772282fd 100644 --- a/g/net/ghttp/http_server_service.go +++ b/g/net/ghttp/http_server_service.go @@ -40,7 +40,7 @@ func (s *Server)appendMethodNameToUriWithPattern(pattern string, name string) st array := strings.Split(pattern, "@") // 分离URI(其实可能包含HTTP Method) uri := array[0] - uri = strings.TrimRight(uri, "/") + "/" + uri = strings.TrimRight(uri, "/") + "/" // 方法名中间存在大写字母,转换为小写URI地址以“-”号链接每个单词 for i := 0; i < len(name); i++ { if i > 0 && gutil.IsLetterUpper(name[i]) { @@ -73,11 +73,19 @@ func (s *Server)BindObject(pattern string, obj interface{}) error { for i := 0; i < v.NumMethod(); i++ { name := t.Method(i).Name key := s.appendMethodNameToUriWithPattern(pattern, name) - m[key] = &HandlerItem{ + m[key] = &HandlerItem { ctype : nil, fname : "", faddr : v.Method(i).Interface().(func(*Request)), } + // 如果方法中带有Index方法,那么额外自动增加一个路由规则匹配主URI + if strings.EqualFold(name, "Index") { + m[pattern] = &HandlerItem { + ctype : nil, + fname : "", + faddr : v.Method(i).Interface().(func(*Request)), + } + } } return s.bindHandlerByMap(m) } @@ -87,17 +95,25 @@ func (s *Server)BindObject(pattern string, obj interface{}) error { func (s *Server)BindObjectMethod(pattern string, obj interface{}, methods string) error { m := make(HandlerMap) for _, v := range strings.Split(methods, ",") { - method := strings.TrimSpace(v) - fval := reflect.ValueOf(obj).MethodByName(method) + name := strings.TrimSpace(v) + fval := reflect.ValueOf(obj).MethodByName(name) if !fval.IsValid() { - return errors.New("invalid method name:" + method) + return errors.New("invalid method name:" + name) } - key := s.appendMethodNameToUriWithPattern(pattern, method) + key := s.appendMethodNameToUriWithPattern(pattern, name) m[key] = &HandlerItem{ ctype : nil, fname : "", faddr : fval.Interface().(func(*Request)), } + // 如果方法中带有Index方法,那么额外自动增加一个路由规则匹配主URI + if strings.EqualFold(name, "Index") { + m[pattern] = &HandlerItem { + ctype : nil, + fname : "", + faddr : fval.Interface().(func(*Request)), + } + } } return s.bindHandlerByMap(m) } @@ -136,11 +152,48 @@ func (s *Server)BindController(pattern string, c Controller) error { continue } key := s.appendMethodNameToUriWithPattern(pattern, name) - m[key] = &HandlerItem{ + m[key] = &HandlerItem { ctype : v.Elem().Type(), fname : name, faddr : nil, } + // 如果方法中带有Index方法,那么额外自动增加一个路由规则匹配主URI + if strings.EqualFold(name, "Index") { + m[pattern] = &HandlerItem { + ctype : v.Elem().Type(), + fname : name, + faddr : nil, + } + } + } + return s.bindHandlerByMap(m) +} + +// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话 +// 第三个参数methods支持多个方法注册,多个方法以英文“,”号分隔,不区分大小写 +func (s *Server)BindControllerMethod(pattern string, c Controller, methods string) error { + m := make(HandlerMap) + cval := reflect.ValueOf(c) + for _, v := range strings.Split(methods, ",") { + name := strings.TrimSpace(v) + ctype := reflect.ValueOf(c).Elem().Type() + if !cval.MethodByName(name).IsValid() { + return errors.New("invalid method name:" + name) + } + key := s.appendMethodNameToUriWithPattern(pattern, name) + m[key] = &HandlerItem { + ctype : ctype, + fname : name, + faddr : nil, + } + // 如果方法中带有Index方法,那么额外自动增加一个路由规则匹配主URI + if strings.EqualFold(name, "Index") { + m[pattern] = &HandlerItem { + ctype : ctype, + fname : name, + faddr : nil, + } + } } return s.bindHandlerByMap(m) } @@ -176,24 +229,3 @@ func (s *Server)BindControllerRest(pattern string, c Controller) error { } return s.bindHandlerByMap(m) } - -// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话 -// 第三个参数methods支持多个方法注册,多个方法以英文“,”号分隔,不区分大小写 -func (s *Server)BindControllerMethod(pattern string, c Controller, methods string) error { - m := make(HandlerMap) - cval := reflect.ValueOf(c) - for _, v := range strings.Split(methods, ",") { - ctype := reflect.ValueOf(c).Elem().Type() - method := strings.TrimSpace(v) - if !cval.MethodByName(method).IsValid() { - return errors.New("invalid method name:" + method) - } - key := s.appendMethodNameToUriWithPattern(pattern, method) - m[key] = &HandlerItem{ - ctype : ctype, - fname : method, - faddr : nil, - } - } - return s.bindHandlerByMap(m) -} \ No newline at end of file diff --git a/geg/frame/mvc/controller/demo/hook.go b/geg/frame/mvc/controller/demo/hook.go deleted file mode 100644 index 23e73fd96..000000000 --- a/geg/frame/mvc/controller/demo/hook.go +++ /dev/null @@ -1,21 +0,0 @@ -package demo - -import "gitee.com/johng/gf/g/net/ghttp" - -func init() { - ghttp.GetServer().BindHandler("/hook", func(r *ghttp.Request){ - r.Response.Write("This is hook content!\n") - }) - ghttp.GetServer().BindHookHandlerInit("/hook", func(r *ghttp.Request){ - r.Response.Write("Init hook 1!\n") - }) - ghttp.GetServer().BindHookHandlerInit("/hook", func(r *ghttp.Request){ - r.Response.Write("Init hook 2!\n") - }) - ghttp.GetServer().BindHookHandlerShut("/hook", func(r *ghttp.Request){ - r.Response.Write("Shut hook 1!\n") - }) - ghttp.GetServer().BindHookHandlerShut("/hook", func(r *ghttp.Request){ - r.Response.Write("Shut hook 2!\n") - }) -} \ No newline at end of file diff --git a/geg/frame/mvc/controller/demo/object.go b/geg/frame/mvc/controller/demo/object.go index 5a9c5b279..73f714129 100644 --- a/geg/frame/mvc/controller/demo/object.go +++ b/geg/frame/mvc/controller/demo/object.go @@ -8,6 +8,10 @@ func init() { ghttp.GetServer().BindObject("/object", &Object{}) } +func (o *Object) Index(r *ghttp.Request) { + r.Response.Write("It's index!") +} + func (o *Object) Show(r *ghttp.Request) { r.Response.Write("It's show time bibi!") } diff --git a/geg/frame/mvc/controller/demo/router.go b/geg/frame/mvc/controller/demo/router.go deleted file mode 100644 index 313cbd5eb..000000000 --- a/geg/frame/mvc/controller/demo/router.go +++ /dev/null @@ -1,12 +0,0 @@ -package demo - -import "gitee.com/johng/gf/g/net/ghttp" - -func init() { - ghttp.GetServer().BindHandler("/list", List) - ghttp.GetServer().Router.SetRule(`\/list\/page\/(\d+)[\/\?]*`, "/list?page=$1&") -} - -func List(r *ghttp.Request) { - r.Response.Write("list page:" + r.Get("page")) -} \ No newline at end of file diff --git a/geg/frame/mvc/controller/demo/router2.go b/geg/frame/mvc/controller/demo/router2.go deleted file mode 100644 index c8fa79d4a..000000000 --- a/geg/frame/mvc/controller/demo/router2.go +++ /dev/null @@ -1,17 +0,0 @@ -package demo - -import "gitee.com/johng/gf/g/net/ghttp" - -func init() { - ghttp.GetServer().BindHandler("/list", List) - ghttp.GetServer().BindHandler("/list/page/2", List2) - ghttp.GetServer().Router.SetRule(`\/list\/page\/(\d+)[\/\?]*`, "/list?page=$1&") -} - -func List1(r *ghttp.Request) { - r.Response.Write("list page:" + r.Get("page")) -} - -func List2(r *ghttp.Request) { - r.Response.Write("customed list page") -} \ No newline at end of file diff --git a/geg/frame/mvc/controller/demo/router_patch.go b/geg/frame/mvc/controller/demo/router_patch.go deleted file mode 100644 index 50f8d505d..000000000 --- a/geg/frame/mvc/controller/demo/router_patch.go +++ /dev/null @@ -1,12 +0,0 @@ -package demo - -import "gitee.com/johng/gf/g/net/ghttp" - -func init() { - ghttp.GetServer().BindHandler("/router-patch", RouterPatch) - ghttp.GetServer().Router.SetPatchRule(`\/list\?page=(\d+)&*`, "/list/page/$1?") -} - -func RouterPatch(r *ghttp.Request) { - r.Response.Write(`page2`) -} \ No newline at end of file diff --git a/geg/net/ghttp/events.go b/geg/net/ghttp/events.go index 55ccfc455..9cf602397 100644 --- a/geg/net/ghttp/events.go +++ b/geg/net/ghttp/events.go @@ -6,7 +6,7 @@ import ( ) func main() { - pattern := "/:name/action" + pattern := "/*" ghttp.GetServer().BindHookHandlerByMap(pattern, map[string]ghttp.HandlerFunc{ "BeforeServe" : func(r *ghttp.Request){ fmt.Println("BeforeServe") }, "AfterServe" : func(r *ghttp.Request){ fmt.Println("AfterServe") },