<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
HttpRouter是一個輕量級但卻非常高效的multiplexer。手冊:
package main import ( "fmt" "github.com/julienschmidt/httprouter" "net/http" "log" ) func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { fmt.Fprint(w, "Welcome!n") } func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { fmt.Fprintf(w, "hello, %s!n", ps.ByName("name")) } func main() { router := httprouter.New() router.GET("/", Index) router.GET("/hello/:name", Hello) log.Fatal(http.ListenAndServe(":8080", router)) }
首先執行:
go get github.com/julienschmidt/httprouter
然後再啟動web服務:
go run xxx.go
和http包的ServeMux用法其實很類似。上面定義了兩個httprouter中的handle,類似於http包中的http.HandlerFunc型別,具體的對應關係後文會解釋,只要認為它是handler,是處理對應請求的就行了。然後使用New()方法建立了範例,並使用GET()方法為兩個模式註冊了對應的handler。
需要注意的是,第二個模式"/hello/:name",它可以用來做命名匹配,類似於正規表示式的命名捕獲分組。後面會詳細解釋用法。
Variables func CleanPath(p string) string type Handle type Param type Params func ParamsFromContext(ctx context.Context) Params func (ps Params) ByName(name string) string type Router func New() *Router func (r *Router) DELETE(path string, handle Handle) func (r *Router) GET(path string, handle Handle) func (r *Router) HEAD(path string, handle Handle) func (r *Router) Handle(method, path string, handle Handle) func (r *Router) Handler(method, path string, handler http.Handler) func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc) func (r *Router) Lookup(method, path string) (Handle, Params, bool) func (r *Router) OPTIONS(path string, handle Handle) func (r *Router) PATCH(path string, handle Handle) func (r *Router) POST(path string, handle Handle) func (r *Router) PUT(path string, handle Handle) func (r *Router) ServeFiles(path string, root http.FileSystem) func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)
httprouter中的Handle類似於http.HandlerFunc,只不過它支援第三個引數Params。
type Handle func(http.ResponseWriter, *http.Request, Params) Handle is a function that can be registered to a route to handle HTTP requests. Like http.HandlerFunc, but has a third parameter for the values of wildcards (variables).
例如前面範例中的Index()和Hello()都是Handle型別的範例。
func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { fmt.Fprint(w, "Welcome!n") } func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { fmt.Fprintf(w, "hello, %s!n", ps.ByName("name")) }
httprouter.Router型別類似於http包中的ServeMux,它實現了http.Handler介面,所以它是一個http.Handler。它可以將請求分配給註冊好的handler。
type Router struct {} func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)
除此之外,Router提供了不少方法,用來指示如何為路徑註冊handler。
func (r *Router) Handle(method, path string, handle Handle) func (r *Router) Handler(method, path string, handler http.Handler) func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc)
httprouter.Handle()用於為路徑註冊指定的Handle,而httprouter.Handle對應於http.HandlerFunc,所以是直接將Handle型別的函數繫結到指定路徑上。同時,它還可以指定http方法:GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS。
這些方法還有對應的各自縮寫:
func (r *Router) DELETE(path string, handle Handle) func (r *Router) GET(path string, handle Handle) func (r *Router) HEAD(path string, handle Handle) func (r *Router) OPTIONS(path string, handle Handle) func (r *Router) PATCH(path string, handle Handle) func (r *Router) POST(path string, handle Handle) func (r *Router) PUT(path string, handle Handle)
例如,Get()等價於route.Handle("GET", path, handle)。
例如上面的範例中,為兩個路徑註冊了各自的httprouter.Handle函數。
router := httprouter.New() router.GET("/", Index) router.GET("/hello/:name", Hello)
Handler()方法是直接為指定http方法和路徑註冊http.Handler;HandlerFunc()方法則是直接為指定http方法和路徑註冊http.HandlerFunc。
type Param struct { Key string Value string } Param is a single URL parameter, consisting of a key and a value. type Params []Param Params is a Param-slice, as returned by the router. The slice is ordered, the first URL parameter is also the first slice value. It is therefore safe to read values by the index. func (ps Params) ByName(name string) string ByName returns the value of the first Param which key matches the given name. If no matching Param is found, an empty string is returned.
Param型別是key/value型的結構,每個分組捕獲到的值都會儲存為此型別。正如前面的範例中:
router.GET("/hello/:name", Hello)
這裡的:name
就是key,當請求的URL路徑為/hello/abc
,則key對應的value為abc。也就是說儲存了一個Param範例:
Param{ Key: "name", Value: "abc", }
更多的匹配用法稍後解釋。
Params是Param的slice。也就是說,每個分組捕獲到的key/value都存放在這個slice中。
ByName(str)方法可以根據Param的Key檢索已經儲存在slice中的Param的Value。正如範例中:
func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { fmt.Fprintf(w, "hello, %s!n", ps.ByName("name")) } router.GET("/hello/:name", Hello)
這裡ByName("name")
將檢索儲存在slice中,Key="name"的Param,且返回這個Param中的Value。
由於Params是slice結構,除了ByName()方法可以檢索key/value,通過slice的方法也可以直接檢索:
ps[0].Key ps[0].Value
httprouter要為路徑註冊handler的適合,路徑可以進行命名捕獲。有兩種命名捕獲的方式:
Syntax Type :name named parameter *name catch-all parameter
其中:name
的捕獲方式是匹配內容直到下一個斜線或者路徑的結尾。例如要為如下路徑註冊handler:
Path: /blog/:category/:post
當請求路徑為:
/blog/go/request-routers match: category="go", post="request-routers" /blog/go/request-routers/ no match, but the router would redirect /blog/go/ no match /blog/go/request-routers/comments no match
*name
的捕獲方式是從指定位置開始(包含字首"/")匹配到結尾:
Path: /files/*filepath /files/ match: filepath="/" /files/LICENSE match: filepath="/LICENSE" /files/templates/article.html match: filepath="/templates/article.html" /files no match, but the router would redirect
再解釋下什麼時候會進行重定向。在Router型別中,第一個欄位控制尾隨斜線的重定向操作:
type Router struct { RedirectTrailingSlash bool ... }
如果請求的URL路徑包含或者不包含尾隨斜線時,但在註冊的路徑上包含了或沒有包含"/"的目標上定義了handler,但是會進行301重定向。簡單地說,不管URL是否帶尾隨斜線,只要註冊路徑不存在,但在去掉尾隨斜線或加上尾隨斜線的路徑上定義了handler,就會自動重定向。
例如註冊路徑為/foo
,請求路徑為/foo/
,會重定向。
下面還有幾種會重定向的情況:
註冊路徑:/blog/:category/:post 請求URL路徑:/blog/go/request-routers/ 註冊路徑:/blog/:category 請求URL路徑:/blog/go 註冊路徑:/files/*filepath 請求URL路徑:/files
func (r *Router) Lookup(method, path string) (Handle, Params, bool)
Lookup根據method+path檢索對應的Handle,以及Params,並可以通過第三個返回值判斷是否會進行重定向。
更多關於Go語言HttpRouter路由使用方法詳解請檢視下面的相關連結
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45