目录
介绍
安装
使用
常用方法介绍
1.初始化路由
2.路由注册
3.子路由的使用
4.定义路由别名
5.静态文件路由
7.生成已注册的URL
8.Walk方法
9.Middleware 中间件
10.开启监听端口:
11.get请求处理:
12.post请求处理
测试
Get请求
Post请求
综合示例
介绍
mux
是一个用来执行http请求的路由和分发的第三方扩展包。mux
其名称来源于HTTP request multiplexer
,类似于官方包http.ServeMux
,mux.Router
将会定义一个路由列表,其中每一个路由都会定义对应的请求url,及其处理方法。
安装
go get -u github.com/gorilla/mux
使用
添加包引用:
import "github.com/gorilla/mux"
常用方法介绍
1.初始化路由
r := mux.NewRouter()
路由路径重定向,StrictSlash如果为true,则如果路由路径为“/path/”,则访问“/path”将执行到前者的重定向,反之亦然。
StrictSlash(true)
2.路由注册
最简单的路由注册:
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")
3.子路由的使用
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)
4.定义路由别名
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).Name("article")
5.静态文件路由
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))))
7.生成已注册的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")
8.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)
}
9.Middleware 中间件
mux同样也支持为路由添加中间件。
最简单的中间件定义:
func loggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Do stuff herelog.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)
10.开启监听端口:
err := http.ListenAndServe(address, router)
11.get请求处理:
//响应数据var res map[string]string = make(map[string]string)var status = http.StatusOK //获得请求参数vals := r.URL.Query()//获得参数name对应的值param, ok := vals["name"]if (!ok) {res["result"] = "fail"res["error"] = "required parameter name is missing"status = http.StatusBadRequest} else {res["result"] = "succ"res["name"] = param[0]status = http.StatusOK}//序列化response, _ := json.Marshal(res)//响应成功写入头部w.WriteHeader(status)//设置返回格式w.Header().Set("Content-Type", "application/json")//写入数据w.Write(response)
}
12.post请求处理
vars := mux.Vars(r)servicename := vars["servicename"]// parse JSON bodyvar req map[string]interface{}//读取bodybody, _ := ioutil.ReadAll(r.Body)//fmt.Println(r.Body)json.Unmarshal(body, &req)//获得body参数对应字符串值servicetype := req["servicetype"].(string)// composite response bodyvar res = map[string]string{"result":"succ", "name":servicename, "type":servicetype}response, _ := json.Marshal(res)w.Header().Set("Content-Type", "application/json")w.Write(response)
测试
Postman插件:一种网页调试与发送网页http请求的chrome插件,很方便的模拟get或者post或其他方式的请求来调试接口。模拟用户HTTP请求的数据发送到服务器,以便开发人员能够及时地作出正确的响应,或者是对产品发布之前的错误信息提前处理,进而保证产品上线后的稳定性和安全性。下载链接:https://www.getpostman.com/downloads/。
Get请求
①在地址栏里输入请求url:http://localhost:8080/api/service/get
②选择“GET”方式,点击"Params",添加添加 key和 value
③点击“send”得到数据
如图:
Post请求
①在地址栏里输入请求url:http://localhost:8080/api/service/myservice/post
②在Body下选择“Raw”,在编辑框中输入你需要提交的参数的键和值,点击“send”提交请求
POST-JSON方式提交
①如果服务端需要请求类型为json,需要在“headers”添加
key:Content-Type , value:application/json
②可先在Body下的选项中点击“Raw”,在右边下拉三角选择“json”,此时第一步中Header需要设置的会自动添加
综合示例
package th_muximport( "strings""flag""fmt""net/http""github.com/gorilla/mux")func Run(){var dir stringflag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")flag.Parse() // 初始化Routerr := mux.NewRouter() // 静态文件路由r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir)))) // 普通路由r.HandleFunc("/", HomeHandler) // 指定hostr.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 herefmt.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)})
}
运行结果截图
刚执行时的注册打印:
注册
依次在浏览器中输入以下地址测试,查看结果:
http://localhost:3000/
hosthttp://127.0.0.1:3000/
hosthttp://localhost:3000/users/5
示例源码:阅读原文,用法文档:https://godoc.org/github.com/gorilla/mux
希望大家关注我的微信公众号,推荐给更多技术极客,日更一篇区块链技术博客不易,有疑问可以后台留言。