**自学习golang以来,无论是beego还是web.go亦或是站长大人的dreamgo的路由,感觉都不明白是怎么写的,下面我把自己的一种实现方式给写出来,希望大家指点一二。**
`目录结构`
```
web
controller
index.go
xxx
router
route.go
util
util.go
view
index.html
main.go #入口
```
`web入口路由handler处理`
```
func main() {
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func handler(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
// 获取路由url地址
path := r.URL.Path
sort_path := path[1:]
// path的情况可能 有/ /facxx.ico /index /index.html /post/2 post提交 get提交
// 分静态资源和请求之分
switch {
case sort_path != "" && sort_path != "favicon.ico":
router.Control(w, r, sort_path)
case sort_path == "favicon.ico":
http.NotFound(w, r)
return
}
}
```
``` 路由映射管理 ```
```
// 路由映射
var m = make(map[string]interface{})
// 配置对应的路由
func init() {
v := new(controller.Index)
m["Index"] = v
}
const (
DEFAULT_CTRL = "Index"
// 这里要注意的是 控制器的方法在反射和定义的时候必须要大写
DEFAULT_ACTION = "Index"
)
// Control
// 路由核心方法
func Control(w http.ResponseWriter, r *http.Request, path string) {
defer r.Body.Close()
routers := routeInfo(path)
// 根据地址获取对应的控制器
ctrl_struct, ok := m[routers[0]]
// 找到对应的控制器
if !ok {
ctrl_struct = m[DEFAULT_CTRL]
}
ctrl := reflect.ValueOf(ctrl_struct)
action := ctrl.MethodByName(routers[1])
k := action.Kind()
if k == reflect.Func {
params := make([]reflect.Value, 2)
params[0] = reflect.ValueOf(w)
params[1] = reflect.ValueOf(r)
action.Call(params)
return
}
http.NotFound(w, r)
return
}
func routeInfo(path string) []string {
arr := strings.Split(path, "/")
// 第一个参数需要是controller
// 第二个参数需要是action
if len(arr) == 1 {
arr = append(arr, DEFAULT_ACTION)
} else {
arr[1] = DEFAULT_ACTION
}
return arr[0:2]
}
```
```Index 控制器 ```
```
type Index struct{}
func (this *Index) Index(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
id := r.Form["id"][0]
// 此处必须是值而不能是指针
result := res.Result{}
result.Code = 0
result.Message = "成功"
result.Data = make(map[string]interface{})
result.Data["id"] = id
fmt.Println(result)
encode_arr, err := json.Marshal(result)
if err != nil {
log.Fatal(err)
return
}
fmt.Println(string(encode_arr))
w.Write(encode_arr)
}
```
``` 这就是我实现的路由 感觉跟网上写的不一样,请指导下 谢谢 ```
dreamgo是使用
DefaultBlogMux.HandleFunc(pattern, handler)
注册路由,而DefaultBlogMux内部还是使用的http.DefaultServeMux。
我感觉你这种方法也可以不用反射,路由表map里面存放func (w http.ResponseWriter, r *http.Request)类型的方法即可,后面路由分发时直接调用。不知道可行不可行
#1