昨天的範例雖然可以成功取得連結中的參數,但使用的是處理字串的方法,在實務上其實不太可行。因為可能不只會有一個參數,也不適合將這邊的邏輯複雜化。所以我們今天講講比較進階的方法可以順利取得網址內的參數,以及利用外部包的情況。
首先我們看一個簡單的例子:
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":3000", nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
keys, ok := r.URL.Query()["key"]
if !ok || len(keys[0]) < 1 {
fmt.Fprint(w, "Url Param 'key' is missing")
return
}
key := keys[0]
fmt.Fprint(w, "Url Param 'key' is: "+string(key))
}
主要的不同,就是在昨天以前我們都是使用r.URL.Path
來取得根目錄後的整段參數作為字串,處理起來其實很沒有效率;今天我們使用的是r.URL.Query()
方法,可以根據參數的關鍵字做搜尋,轉成陣列,使用上相當靈活方便。
我們來觀察一下使用情況
http://localhost:3000/?key=abc
> Url Param 'key' is: abc
http://localhost:3000/?shop=1&key=abc&page=1
> Url Param 'key' is: abc //參數的數量與位置不會影響
http://localhost:3000/key/abc
> Url Param 'key' is missing //無法處理這種形式的參數
雖然之前說go內建的方法對伺服器而言就已經足夠,但有時候我們為了追求更好的效果,還是會適度依賴一些外掛包。為了實作常見的參數型網址的結構,我們來使用看看引入外部方法。我們使用的外掛包是「mux」,我們先來看看範例:
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/books/{title}/page/{page}", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
title := vars["title"]
page := vars["page"]
fmt.Fprintf(w, "You've requested the book: %s on page %s\n", title, page)
})
http.ListenAndServe(":3000", r)
}
如果你照樣貼上,應該會出現警告,表示找不到「github.com/gorilla/mux」。go一般的做法是先安裝下來,所以我們需要執行:
go get github.com/gorilla/mux
go install github.com/gorilla/mux
如果還是找不到,記得將編輯器重啟,並且檢查GOPATH
是否有設定正確,如果有的話,應該可以成功找到路徑。
// 檢查有沒有正確設定GOPATH的方法
$ echo $GOPATH
> /Users/Chenbater/go
//在你的環境下,可能會在不同位置,要看你安裝在哪裡
如果安裝沒問題,我們試著訪問http://localhost:3000/books/harrypoter/page/301,你在瀏覽器上就可以看到「You've requested the book: harrypoter on page 301」有沒有覺得很神奇啊XD