##############

地址:​​https://github.com/gorilla/mux​

 

 

 

安装

go get -u github.com/gorilla/mux

 

使用

添加包引用:

"github.com/gorilla/mux"

 

常用方法介绍

初始化路由

r := mux.NewRouter()

 

路由注册

最简单的路由注册:

r.HandleFunc("/", HomeHandler)

 

其中代码中的第一个参数为请求url,第二个参数为请求的处理函数,该函数可简单的定义为以下代码:

func HomeHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "this is home")
}

 

带有变量的url路由注册:
其中参数可使用正则表达式匹配

r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)

 

指定Host:

r.Host("www.example.com")

 

指定http方法:

r.Methods("GET", "POST")

 

指定URL安全策略:

r.Schemes("https")

 

增加URL前缀:

r.PathPrefix("/products/")

 

添加请求头:

r.Headers("X-Requested-With", "XMLHttpRequest")

 

添加请求参数:

r.Queries("key", "value")

 

组合使用:

r.HandleFunc("/products", ProductsHandler).
Host("www.example.com").
Methods("GET").
Schemes("http")

 

子路由的使用:

r := mux.NewRouter()
s := r.PathPrefix("/products").Subrouter()
// "/products/"s.HandleFunc("/", ProductsHandler)
// "/products/{key}/"s.HandleFunc("/{key}/", ProductHandler)
// "/products/{key}/details"s.HandleFunc("/{key}/details", ProductDetailsHandler)

 

定义路由别名:

r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).Name("article")

 

静态文件路由:

flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")
flag.Parse()
r := mux.NewRouter() // This will serve files under http://localhost:8000/static/<filename>
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir))))

 

生成已注册的URL:
生成已注册的url需要用到路由的别名,代码如下:

url, err := r.Get("router_name").URL("key1", "val1", "key2", "val2")

 

例如:

r := mux.NewRouter()
r.Host("{subdomain}.domain.com").
Path("/articles/{category}/{id:[0-9]+}").
Queries("filter", "{filter}").
HandlerFunc(ArticleHandler).
Name("article")

// url.String() will be "http://news.domain.com/articles/technology/42?filter=gorilla"
url, err := r.Get("article").URL("subdomain", "news",
"category", "technology",
"id", "42",
"filter", "gorilla")

 

Walk方法:
walk方法可以遍历访问所有已注册的路由,例如以下代码:

func main() {
r := mux.NewRouter()
r.HandleFunc("/", handler)
r.HandleFunc("/products", handler).Methods("POST")
r.HandleFunc("/articles", handler).Methods("GET")
r.HandleFunc("/articles/{id}", handler).Methods("GET", "PUT")
r.HandleFunc("/authors", handler).Queries("surname", "{surname}")
err := r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
pathTemplate, err := route.GetPathTemplate() if err == nil {
fmt.Println("ROUTE:", pathTemplate)
}
pathRegexp, err := route.GetPathRegexp() if err == nil {
fmt.Println("Path regexp:", pathRegexp)
}
queriesTemplates, err := route.GetQueriesTemplates() if err == nil {
fmt.Println("Queries templates:", strings.Join(queriesTemplates, ","))
}
queriesRegexps, err := route.GetQueriesRegexp() if err == nil {
fmt.Println("Queries regexps:", strings.Join(queriesRegexps, ","))
}
methods, err := route.GetMethods() if err == nil {
fmt.Println("Methods:", strings.Join(methods, ","))
}
fmt.Println() return nil
}) if err != nil {
fmt.Println(err)
}

http.Handle("/", r)
}

 

Middleware 中间件

mux同样也支持为路由添加中间件。

最简单的中间件定义:

func loggingMiddleware(next http.Handler) http.Handler {    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        // Do stuff here
log.Println(r.RequestURI) // Call the next handler, which can be another middleware in the chain, or the final handler.
next.ServeHTTP(w, r)
})
}
中间件使用:

r := mux.NewRouter()
r.HandleFunc("/", handler)
r.Use(loggingMiddleware)

 

综合示例

package th_muximport(    "strings"
"flag"
"fmt"
"net/http"
"github.com/gorilla/mux")func Run(){
var dir string
flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")
flag.Parse() // 初始化Router
r := mux.NewRouter() // 静态文件路由
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir)))) // 普通路由
r.HandleFunc("/", HomeHandler) // 指定host
r.HandleFunc("/host", HostHandler).Host("localhost") // 带变量的url路由
r.HandleFunc("/users/{id}", GetUserHandler).Methods("Get").Name("user")

url, _ := r.Get("user").URL("id", "5")
fmt.Println("user url: ", url.String()) // 遍历已注册的路由
r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
pathTemplate, err := route.GetPathTemplate() if err == nil {
fmt.Println("ROUTE:", pathTemplate)
}
pathRegexp, err := route.GetPathRegexp() if err == nil {
fmt.Println("Path regexp:", pathRegexp)
}
queriesTemplates, err := route.GetQueriesTemplates() if err == nil {
fmt.Println("Queries templates:", strings.Join(queriesTemplates, ","))
}
queriesRegexps, err := route.GetQueriesRegexp() if err == nil {
fmt.Println("Queries regexps:", strings.Join(queriesRegexps, ","))
}
methods, err := route.GetMethods() if err == nil {
fmt.Println("Methods:", strings.Join(methods, ","))
}
fmt.Println() return nil
})

r.Use(TestMiddleware)
http.ListenAndServe(":3000", r)
}func HomeHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "this is home")
}func HostHandler(w http.ResponseWriter, r *http.Request){
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "the host is localhost")
}func GetUserHandler(w http.ResponseWriter, r *http.Request){
vars := mux.Vars(r)
w.WriteHeader(http.StatusOK)

fmt.Fprint(w, "this is get user, and the user id is ", vars["id"])
}func TestMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Do stuff here
fmt.Println("middleware print: ", r.RequestURI) // Call the next handler, which can be another middleware in the chain, or the final handler.
next.ServeHTTP(w, r)
})
}

 

运行结果截图
刚执行时的注册打印: