获取 Golang HTTP 或 Gorilla 包中的路由和参数列表

Get a list of routes and params in Golang HTTP or Gorilla package

当我编写这样一个简单的 Web 应用程序时:

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/about", handler)
    http.ListenAndServe(":8080", nil)
}

如何找到我在网络应用程序中定义的路由和参数列表? 例如,在此示例中找到“/about”。

编辑 1: 如何获得这个参数和路线?

gorilla.HandleFunc(`/check/{id:[0-9]+}`, func(res http.ResponseWriter, req *http.Request) {
    res.Write([]byte("Regexp works :)"))
})

您可以使用 http.DefaultServeMux(键入 ServeMux)并检查它。使用 reflect 包,您可以 ValueOf 默认多路复用器并提取 m 属性,这是您的路线图。

v := reflect.ValueOf(http.DefaultServeMux).Elem()
fmt.Printf("routes: %v\n", v.FieldByName("m"))

upd:

如果您使用 net/http,那么您应该在您实际完成任何请求之前实施提取参数;否则你可以使用 r.URL.Query()

访问参数

如果你使用 gorilla/mux 而不是 elithrar 提到的你应该使用 Walk:

func main:

r := mux.NewRouter()
r.HandleFunc("/path/{param1}", handler)

err := r.Walk(gorillaWalkFn)
if err != nil {
    log.Fatal(err)
}

func gorillaWalkFn:

func gorillaWalkFn(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
    path, err := route.GetPathTemplate()
    return nil
}

path 变量包含您的模板:

"/路径/{param1}"

但您应该手动提取参数。

您可以在 HTTP 包中看到路由列表。

http.HandleFunc("/favicon.ico", func(res http.ResponseWriter, req *http.Request) {
    http.ServeFile(res, req, "favicon.ico")
})
http.HandleFunc(`/check`, func(res http.ResponseWriter, req *http.Request) {
    res.Write([]byte("Regexp works :)"))
})

httpMux := reflect.ValueOf(http.DefaultServeMux).Elem()
finList := httpMux.FieldByIndex([]int{1})
fmt.Println(finList)

我想是一个需要改进的答案。

它提供了从路由路径模板字符串中提取参数的缺失代码。


var pathTemplateRegex = regexp.MustCompile(`\{(\?[^}])+\}`)

func getRouteParams(router *mux.Router, route string) []string {
    r := router.Get(route)
    if r == nil {
        return nil
    }
    t, _ := r.GetPathTemplate()
    params := pathTemplateRegex.FindAllString(t, -1)
    for i, p := range params {
        p = strings.TrimPrefix(p, "{")
        p = strings.TrimSuffix(p, "}")
        if strings.ContainsAny(p, ":") {
            p = strings.Split(p, ":")[0]
        }
        params[i] = p
    }
    return params
}