Gorilla mux 可选查询值
Posted
技术标签:
【中文标题】Gorilla mux 可选查询值【英文标题】:Gorilla mux optional query values 【发布时间】:2018-01-04 19:44:54 【问题描述】:我一直在做一个使用 gorilla/mux 作为路由器的 Go 项目。
我需要能够将查询值与路由关联,但这些值应该是可选的。
这意味着我想在同一个处理程序中同时捕获 /articles/123
和 /articles/123?key=456
。
为了完成,我尝试使用接受键/值对的r.Queries
方法:
路由器。
Path("/articles/id:[0-9]+").Queries("key", "[0-9]*?")
但这使得只有值 (456
) 是可选的,而不是 key
。
所以/articles/123?key=456
和/articles/123?key=
都有效,但/articles/123
无效。
编辑:另一个要求是,在注册路线之后,我想以编程方式构建它们,我似乎无法弄清楚如何使用r.Queries
,即使文档明确指出这是可能的(@ 987654321@).
@jmaloney 回答有效,但不允许从名称构建 URL。
【问题讨论】:
一种方法:***.com/questions/43379942/… @smarx 我已经看到了这个问题,但它对我不起作用有两个原因:1. 它阻止我在处理程序 2 中使用mux.Vars(req)["tab"]
。它没有允许我按名称构建注册 URL(我已经更新了问题)
【参考方案1】:
似乎处理 可选 URL 参数的最佳方法是在没有它们的情况下将您的路由器定义为正常,然后像这样解析可选参数:
urlParams := request.URL.Query()
这会返回一个映射,其中包含作为键/值对的 URL 参数。
【讨论】:
【参考方案2】:我只会注册你的处理程序两次。
router.Path("/articles/id:[0-9]+").
Queries("key", "[0-9]*?").
HandlerFunc(YourHandler).
Name("YourHandler")
router.Path("/articles/id:[0-9]+").HandlerFunc(YourHandler)
这是一个演示的工作程序。请注意,我使用r.FormValue
来获取查询参数。
注意:请确保您拥有最新版本 go get -u github.com/gorilla/mux
,因为最近修复了未添加构建 URL 的查询参数错误。
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
)
var router = mux.NewRouter()
func main()
router.Path("/articles/id:[0-9]+").Queries("key", "key").HandlerFunc(YourHandler).Name("YourHandler")
router.Path("/articles/id:[0-9]+").HandlerFunc(YourHandler)
if err := http.ListenAndServe(":9000", router); err != nil
log.Fatal(err)
func YourHandler(w http.ResponseWriter, r *http.Request)
id := mux.Vars(r)["id"]
key := r.FormValue("key")
u, err := router.Get("YourHandler").URL("id", id, "key", key)
if err != nil
http.Error(w, err.Error(), 500)
return
// Output:
// /articles/10?key=[key]
w.Write([]byte(u.String()))
【讨论】:
我尝试过这样做,并且成功了,尽管我不知道这是否是黑客行为。唯一的问题是我想使用注册的 URL 按名称反向构建 URL 并使用它们处理查询值,但它似乎不起作用。我会更新问题。 @stassinari 我认为我最近的编辑应该可以解决您的问题。 谢谢@jmaloney,我能够让它工作。但是有一个问题:您使用r.FormValue
而不是mux.Vars
有什么原因吗?我似乎能够让它工作
另外,为了能够使用和不使用参数来构建 URL,我对路由使用了两个不同的名称,就像你的方法一样,一个名称丢失了,并且用两个“重载”了路由相同的名称与多路复用器混淆,似乎不起作用。
@stassinari 我使用r.FormValue
,因为如果找不到密钥,它将返回一个空字符串,如果请求转到第二个处理程序,则使用mux.Vars
将找不到mux.Vars
,处理这种情况还使您必须检查地图是否具有该值。我只使用查询参数“命名”了路由,因为使用空白查询构建 url 仍然有效并且导致代码和逻辑更少。例如,在上面的代码中,如果用户点击第二条路线,输出将只是/articles/10?key=
,这很好。【参考方案3】:
如果您注册查询参数,则它们是必需的doc:
路由中定义的所有变量都是必需的,其值必须符合相应的模式。
因为这些参数是可选的,您只需要在处理函数中检查它们:id, found := mux.Vars(r)["id"]
。其中found
将显示查询中的参数是否存在。
【讨论】:
这才是真正的答案。以上是关于Gorilla mux 可选查询值的主要内容,如果未能解决你的问题,请参考以下文章
GolangWeb 入门 08 集成 Gorilla Mux