改进路由解析优先级设计,完善MVC示例代码

This commit is contained in:
John
2018-01-03 15:27:43 +08:00
parent db71e4c1d1
commit ce3b573c67
12 changed files with 87 additions and 80 deletions

View File

@ -54,11 +54,6 @@ func (r *Response) WriteJson(result int, message string, data []byte) error {
return nil
}
// 返回内容编码
func (r *Response) WriteHeaderEncoding(encoding string) {
r.Header().Set("Content-Type", "text/plain; charset=" + encoding)
}
// 获取当前缓冲区中的数据
func (r *Response) Buffer() []byte {
r.bufmu.RLock()

View File

@ -5,25 +5,26 @@
// You can obtain one at https://gitee.com/johng/gf.
//
// 路由管理
// 路由管理.
// 路由规则按照传入的优先级进行解析
package grouter
import (
"sync"
"sort"
"bytes"
"errors"
"strings"
"gitee.com/johng/gf/g/util/gregx"
"gitee.com/johng/gf/g/container/gmap"
"gitee.com/johng/gf/g/util/gutil"
)
// 路由管理对象
type Router struct {
dmu sync.RWMutex // 解析规则互斥锁
pmu sync.RWMutex // 打包规则互斥锁
dkeys []string // 解析规则排序键名
pkeys []string // 打包规则排序键名
dmu sync.RWMutex // 解析规则互斥锁
pmu sync.RWMutex // 打包规则互斥锁
dkeys []string // 解析规则排序键名
pkeys []string // 打包规则排序键名
drules *gmap.StringStringMap // 解析规则
prules *gmap.StringStringMap // 打包规则
}
@ -39,53 +40,41 @@ func New() *Router {
// `\/([\w\.\-]+)\/([\w\.\-]+)\/page\/([\d\.\-]+)[\/\?]*`, "/user/list/page/2"
func (r *Router) SetRule(rule, replace string) {
r.drules.Set(rule, replace)
r.updateDispatchKeys()
}
// 批量设置解析规则
func (r *Router) SetRules(rules map[string]string) {
r.drules.BatchSet(rules)
r.updateDispatchKeys()
if !gutil.StringInArray(r.dkeys, rule) {
r.dmu.Lock()
r.dkeys = append(r.dkeys, rule)
r.dmu.Unlock()
}
}
// 删除解析规则
func (r *Router) RemoveRule(rule string) {
r.drules.Remove(rule)
r.updateDispatchKeys()
if i := gutil.StringSearch(r.dkeys, rule); i != -1 {
r.drules.Remove(rule)
r.dmu.Lock()
r.dkeys = append(r.dkeys[ : i], r.dkeys[i + 1 : ]...)
r.dmu.Unlock()
}
}
// 设置打包规则
func (r *Router) SetPatchRule(rule, replace string) {
r.prules.Set(rule, replace)
r.updatePatchKeys()
}
// 批量设置打包规则
func (r *Router) SetPatchRules(rules map[string]string) {
r.prules.BatchSet(rules)
r.updatePatchKeys()
if !gutil.StringInArray(r.pkeys, rule) {
r.pmu.Lock()
r.pkeys = append(r.pkeys, rule)
r.pmu.Unlock()
}
}
// 删除打包规则
func (r *Router) RemovePatchRule(rule string) {
r.prules.Remove(rule)
r.updatePatchKeys()
}
// 内部更新解析索引规则排序,便于运行时使用
func (r *Router) updateDispatchKeys() {
r.dmu.Lock()
defer r.dmu.Unlock()
r.dkeys = r.drules.Keys()
sort.Slice(r.dkeys, func(i, j int) bool { return len(r.dkeys[i]) > len(r.dkeys[j]) })
}
// 内部更新所打包引规则排序,便于运行时使用
func (r *Router) updatePatchKeys() {
r.pmu.Lock()
defer r.pmu.Unlock()
r.pkeys = r.prules.Keys()
sort.Slice(r.pkeys, func(i, j int) bool { return len(r.pkeys[i]) > len(r.pkeys[j]) })
if i := gutil.StringSearch(r.pkeys, rule); i != -1 {
r.prules.Remove(rule)
r.pmu.Lock()
r.pkeys = append(r.pkeys[ : i], r.pkeys[i + 1 : ]...)
r.pmu.Unlock()
}
}
// 解析URI

View File

@ -7,7 +7,7 @@
// 其他工具包
package gutil
// 便利数组查找字符串索引位置,如果不存在则返回-1
// 便利数组查找字符串索引位置,如果不存在则返回-1,使用完整遍历查找
func StringSearch (a []string, s string) int {
for i, v := range a {
if s == v {

View File

@ -0,0 +1,21 @@
package demo
import "gitee.com/johng/gf/g/net/ghttp"
func init() {
ghttp.GetServer().BindHandler("/apple", Apple)
ghttp.GetServer().BindHandler("/pen", Pen)
ghttp.GetServer().BindHandler("/apple-pen", ApplePen)
}
func Apple(r *ghttp.Request) {
r.Response.WriteString("Apple")
}
func Pen(r *ghttp.Request) {
r.Response.WriteString("Pen")
}
func ApplePen(r *ghttp.Request) {
r.Response.WriteString("Apple-Pen")
}

View File

@ -5,15 +5,12 @@ import (
"gitee.com/johng/gf/g/net/ghttp"
)
func init() {
ghttp.GetServer().BindHandler("/cookie", Cookie)
}
// 用于函数映射
func Cookie(r *ghttp.Request) {
datetime := r.Cookie.Get("datetime")
r.Cookie.Set("datetime", gtime.Datetime())
r.Response.WriteString("datetime:" + datetime)
}

View File

@ -2,13 +2,8 @@ package demo
import "gitee.com/johng/gf/g/net/ghttp"
// 初始化控制器对象并绑定操作到Web Server
func init() {
// 将URI映射到指定的方法中执行
ghttp.GetServer().BindHandler("/hello", Hello)
}
// 用于函数映射
func Hello(r *ghttp.Request) {
r.Response.WriteString("Hello World!")
ghttp.GetServer().BindHandler("/", func(r *ghttp.Request){
r.Response.WriteString("Hello World!")
})
}

View File

@ -9,7 +9,22 @@ func init() {
ghttp.GetServer().BindObjectRest("/object-rest", &ObjectRest{})
}
// RESTFul - GET
func (o *ObjectRest) Get(r *ghttp.Request) {
r.Response.WriteString("It's show time bibi!")
r.Response.WriteString("RESTFul HTTP Method GET")
}
// RESTFul - POST
func (c *ObjectRest) Post(r *ghttp.Request) {
r.Response.WriteString("RESTFul HTTP Method POST")
}
// RESTFul - DELETE
func (c *ObjectRest) Delete(r *ghttp.Request) {
r.Response.WriteString("RESTFul HTTP Method DELETE")
}
// 该方法无法映射,将会无法访问到
func (c *ObjectRest) Hello(r *ghttp.Request) {
r.Response.WriteString("Hello")
}

View File

@ -1,19 +1,16 @@
package demo
import (
"gitee.com/johng/gf/g/net/ghttp"
"strconv"
"gitee.com/johng/gf/g/net/ghttp"
)
func init() {
ghttp.GetServer().BindHandler("/session", Session)
}
// 用于函数映射
func Session(r *ghttp.Request) {
id := r.Session.GetInt("id")
r.Session.Set("id", id + 1)
r.Response.WriteString("id:" + strconv.Itoa(id))
}

View File

@ -14,7 +14,9 @@ type ControllerUser struct {
// 初始化控制器对象并绑定操作到Web Server
func init() {
// 绑定控制器到指定URI所有控制器的公开方法将会映射到指定URI末尾
// 例如该方法执行后,查看效果可访问:http://127.0.0.1:8199/user/info
// 例如该方法执行后,查看效果可访问:
// http://127.0.0.1:8199/user/name
// http://127.0.0.1:8199/user/age
ghttp.GetServer().BindController("/user", &ControllerUser{})
}
@ -23,10 +25,9 @@ func (c *ControllerUser) Name() {
c.Response.WriteString("John")
}
// 定义操作逻辑 - 展示模板
func (c *ControllerUser) Info() {
c.View.Assign("name", "john")
c.View.Display("user/index")
// 定义操作逻辑 - 展示年龄
func (c *ControllerUser) Age() {
c.Response.WriteString("18")
}

9
geg/net/ghttp/hello.go Normal file
View File

@ -0,0 +1,9 @@
package main
import "gitee.com/johng/gf/g/net/ghttp"
func init() {
ghttp.GetServer().BindHandler("/", func(r *ghttp.Request) {
r.Response.WriteString("Hello World!")
})
}

View File

@ -1,12 +0,0 @@
package main
import "gitee.com/johng/gf/g/net/ghttp"
func Hello(r *ghttp.Request) {
r.Response.WriteString("Hello World!")
}
func main() {
s := ghttp.GetServer()
s.BindHandler("/", Hello)
s.Run()
}

View File

@ -5,6 +5,6 @@ import "gitee.com/johng/gf/g/net/ghttp"
func main() {
s := ghttp.GetServer()
s.SetIndexFolder(true)
s.SetServerRoot("/tmp")
s.SetServerRoot("/home/www/")
s.Run()
}