路由规则完善

This commit is contained in:
John
2018-04-16 16:23:34 +08:00
parent b3eccd0633
commit 83988d4a2b
9 changed files with 74 additions and 99 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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)
}

View File

@ -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")
})
}

View File

@ -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!")
}

View File

@ -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"))
}

View File

@ -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")
}

View File

@ -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(`<a href="/list?page=2&ajax=1">page2</a>`)
}

View File

@ -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") },