What you are wasting today is tomorrow for those who died yesterday; what you hate now is the future you can not go back.
你所浪费的今天是昨天死去的人奢望的明天; 你所厌恶的现在是未来的你回不去的曾经。
最近公司有一个项目不算大,但是流量预计不小,分配到我这来了,要求快速上线,由于本人研究Golang两个多月(本人愚钝),加上对GOlang的痴迷,考虑偷偷的(其实是项目总监被我说服了)使用go来写web服务。 看到这我只能说,瞎扯淡啥!!
上菜:
首先自定义路由的前提是路由对象实现ServeHTTP方法
自定义路由写法一:
1. 路由结构体对象定义
type Router struct {
Route map[string]map[string]http.HandlerFunc
}
Route属性的类型是map , 其中一维的键String表示请求method比如post, get 等。二维的键string表示
要匹配的URL地址, http.HandlerFunc当然就是处理URL请求的具体方法。
2. URL路由表初始化
// 路由表初始化
func (r *Router) HandleFunc(method, path string, f http.HandlerFunc) {
method = strings.ToUpper(method)
if r.Route == nil {
r.Route = make(map[string]map[string]http.HandlerFunc)
}
if r.Route[method] == nil {
r.Route[method] = make(map[string]http.HandlerFunc)
}
r.Route[method][path] = f
}
当然首先要初始化Map,有几个就初始化几个, 否则就会报错哦。初始化后,调用方就可以使用
route.HandleFunc("GET", "/", HomeHandler)
此种方式初始化路由表了。
3. 实现路由核心处理ServeHTTP方法
func (r *Router) ServeHTTP(res http.ResponseWriter, req *http.Request) {
// 此处我做个很多关于http请求header的限制,一级业务版本处理,就不公布出来了
// ....
// 正常路由
if f, ok := r.Route[req.Method][req.URL.Path]; ok {
f(res, req)
//静态文件路由
} else if strings.HasPrefix(req.URL.String(), staticHttpPath){
staticFile := http.StripPrefix(staticHttpPath, http.FileServer(http.Dir(staticDirPath)))
staticFile.ServeHTTP(res, req)
// 404友好处理
}else {
// 由于此项目目的是提供接口和WEB HTML服务,所以此处本人做了一系列的url处理
}
}
另外本人还根据业务做了一些关于web服务器的友好调用处理,比如开启关闭header检测, 服务下线上线处理等等。如果各位亲爱的【码友】还有其他好的建议,请赐教.^_^
自定义路由写法二:
此写法类似与MVC
1. 定义控制器结构体对象
type UrlHandlerController struct {
Function func(http.ResponseWriter, *http.Request)
Method string
Pattern string
}
Pattern就是要匹配的URL地址。
2. 定义路由对象
var mux []UrlHandlerController
调用方在调用过程中就会是用 mux = append(mnx, UrlHandlerController{ XXXFUNC, "POST", "/index" }) 此种方式调用初始化路由表。
3. 定义路由对象
type httpHandler struct{}
4.实现路由核心逻辑
func (*httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// 当然无法避免的Header头处理检测
// t := time.Now()
// 此处有一个不好的写法就是 UrlHandlerController变量最好不要跟已存在的类型重名,否则........
for _, UrlHandlerController := range mux {
if m, _ := regexp.MatchString(UrlHandlerController.Pattern, r.URL.Path); m {
if r.Method == UrlHandlerController.Method {
UrlHandlerController.Function(w, r)
// 做一些日志等的处理
return
}
}
}
// 此处做需要根据项目做一个具体的优化处理:个人建议
io.WriteString(w, "")
return
}
其实核心的处理就是简单的查找路由地址, 找到了就请求改地址的处理方法。
如果码友们有好的建议,请留下你的痕迹
有疑问加站长微信联系(非本文作者)