@Controller
o := odserver.Default()
o.Start("/main").
Target("/test/").Get(HelloServer).Post(HelloServer).Delete(HelloServer).And().
Target("/test2").Get(HelloServer2)
o.Start("/{test}/main/").Target("/number/{number}").
Get(HelloServer3).Post(HelloServer4)
http.ListenAndServe(":8080",o)
func HelloServer3(c *odserver.Context) {
fmt.Fprint(c.Rw, c.Params)
}
\w*/{test}/main/number/{number}/\w*/main/number/\w*
o.Start("/main").
Target("/test/").Get(HelloServer).Post(HelloServer).Delete(HelloServer).And().
Target("/test2").Get(HelloServer2)
HandlerObject
type FuncObject struct {
params []string
//对应编写的接口,IHandlerFunc只是个空接口
f IHandlerFunc
exist bool
*httpConfig
}
//方法函数映射,0代表GET方法下的接口
type methodFuncs []FuncObject
/**
关键struct,代表每个实体的请求
*/
type HandlerObject struct {
*Router
//对应占位符的参数
params []string
//对该请求的http配置
*httpConfig
//请求路径 即start+target的路径
path string
startPath string
//方法函数映射
methodFuncs methodFuncs
}
HandlerObjectRouterRoutermap[string]*HandlerObject
func NewRouter() *Router {
return &Router{
handler: make(map[string]*HandlerObject),
regexpMap: make(map[*regexp.Regexp]*HandlerObject),
}
}
type Router struct {
handler
regexpMap
}
regexpMap
func (r *Router) doUrlMapping(url string, method int) (*HandlerObject,bool) {
ch := make(chan *HandlerObject)
//精准匹配
go func() {
if ho, ok := r.handler[url]; ok {
ch <- ho
}
}()
//正则匹配
go func() {
for k, v := range r.regexpMap {
if k.MatchString(url) {
pathArray := strings.Split(url, "/")[1:]
regexpArray := strings.Split(k.String(), "/")[1:]
if len(pathArray) == len(regexpArray) {
//设置参数
paramsNum := 0
for i := 0; i < len(pathArray); i++ {
if matcher.IsPattern(regexpArray[i]) {
v.params[paramsNum] = pathArray[i]
paramsNum++
}
}
v.params = v.params[:paramsNum]
}
ch <- v
}
}
}()
select {
case ho := <-ch:
{
return ho,true
}
case <-time.After(2e6):
{
return &HandlerObject{},false
}
}
}
注册接口的代码如下
func (r *Router) Start(url string) *HandlerObject {
return NewHandlerObject(r, AddSlash(url))
}
func (ho *HandlerObject) And() *HandlerObject {
if ho.Router == nil || ho.startPath == "" {
panic("ho.Router is nil or startPath is unknown,maybe u should use Start()")
}
return NewHandlerObject(ho.Router, ho.startPath)
}
func (ho *HandlerObject) Target(url string) *HandlerObject {
//设置完整的路径
if ho.startPath == "/" {
ho.path = ho.startPath + DeleteSlash(url)
} else {
if strings.HasSuffix(ho.startPath, "/") {
url = DeleteSlash(url)
} else {
url = AddSlash(url)
}
ho.path = ho.startPath + url
}
//尝试将url转换成正则表达式,如果没有占位符,则转换不成功
pattern, ok := matcher.ToPattern(ho.path)
if ok {
ho.path = pattern
re, err := regexp.Compile(pattern)
if err != nil {
panic("error compile pattern:" + pattern)
}
ho.Router.regexpMap[re] = ho
} else {
ho.handler[ho.path] = ho
}
return ho
}
func AddSlash(s string) string {
if !strings.HasPrefix(s, "/") {
s = "/" + s
}
return s
}
func DeleteSlash(s string) string {
if strings.HasPrefix(s, "/") {
array := strings.SplitN(s, "/", 2)
s = array[1]
}
return s
}
func (ho *HandlerObject) Get(f IHandlerFunc) *HandlerObject {
if ho.methodFuncs[GET].exist {
panic("GetFunc has existed")
}
ho.methodFuncs[GET] = NewFuncObject(f)
return ho
}
ContextRequestresponseWriterRequestresponseWriter
type Context struct {
Req Request
Rw responseWriter
//对应restful的参数值
Params []string
}
源码路径:https://gitee.com/1995zzf/go-oneday
路漫漫其修远兮,客官点个赞呗