在Go(语言)中注册处理程序时,是否可以在模式中指定通配符?
例如:
1 | http.HandleFunc("/groups/*/people", peopleInGroupHandler) |
其中
- 我可以看看您输入字符串的示例吗,请问您当前正在获取匹配项吗?
- 请访问goweb.googlecode.com,该语言在Go中提供了Ruby on Rails样式路线的支持-即goweb.MapFunc(" / people / {person_id} / groups / {group_id}",处理程序)
http.Handler和http.HandleFunc的模式不是正则表达式或glob。无法指定通配符。它们记录在这里。
也就是说,创建自己的可以使用正则表达式或所需的任何其他模式的处理程序并不难。这是一个使用正则表达式(已编译,但未经测试)的表达式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | type route struct { pattern *regexp.Regexp handler http.Handler } type RegexpHandler struct { routes []*route } func (h *RegexpHandler) Handler(pattern *regexp.Regexp, handler http.Handler) { h.routes = append(h.routes, &route{pattern, handler}) } func (h *RegexpHandler) HandleFunc(pattern *regexp.Regexp, handler func(http.ResponseWriter, *http.Request)) { h.routes = append(h.routes, &route{pattern, http.HandlerFunc(handler)}) } func (h *RegexpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { for _, route := range h.routes { if route.pattern.MatchString(r.URL.Path) { route.handler.ServeHTTP(w, r) return } } // no pattern matched; send 404 response http.NotFound(w, r) } |
- 当我想在Go中使用Rails样式的路线上的红宝石时,我启动了goweb项目(请参阅goweb.googlecode.com),该项目允许这种样式的路线映射:goweb.MapFunc(" / people / {person_id}",handler)
- Gorillatoolkit在实现用于处理路由的PAT和MUX方面做得非常出色。唯一的问题是它运行缓慢,我尚未审查代码。至少在他们的API中,可以命名参数...这就是这种功能的全部重点。上面的代码没有提供任何复杂的内容,没有命名元素就可能没有用。
-
如果您只是在寻找"否则"
* 式的包罗万象,那么文档中要注意的是the pattern"" matches all paths not matched by other registered patterns -
也许
(h *RegexpHandler) Handler 应该是(h *RegexpHandler) Handle ?看到这里:golang.org/pkg/net/http/#ServeMux.Handle :) -
@Coaku在这里使用
(h *RegexpHandler) Handler 是可以的,因为只有RegexpHandler 的方法ServeHTTP 很重要。 -
如何将代码集成到
nethttp 的原始示例中。你能举一个完整的例子吗?谢谢。 - 这次真是万分感谢!我刚刚使用您的代码提交了一个示例答案。
自2011年以来,您现在(2014年以上)可以找到其他解决方案。
例如,大猩猩Web工具包的mux软件包提供了所有种类的路由选项:
- 使用可选的正则表达式在请求路径上进行模式匹配。
- 在URL主机和方案,请求方法,标头和查询值上匹配。
- 根据自定义功能进行匹配。
- 使用子路由器进行简单的嵌套路由。
可以很容易地将其集成到任何BYOR(自带路由器)http库中,例如negroni。
这是文章"大猩猩vs帕特vs路线:多人对决"的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package main import ( "github.com/gorilla/mux" "log" "net/http" ) func main() { rtr := mux.NewRouter() rtr.HandleFunc("/user/{name:[a-z]+}/profile", profile).Methods("GET") http.Handle("/", rtr) log.Println("Listening...") http.ListenAndServe(":3000", nil) } func profile(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) name := params["name"] w.Write([]byte("Hello" + name)) } |
Sometimes better not to just use yet another"magic" package, but understand what's going on under the hood
在这种情况下,"魔术"在"
这个想法是提取命名变量,组装要匹配的正则表达式,创建"反向"模板以构建URL,并编译正则表达式以验证URL构建中使用的变量值。
- 因为它是新的。给它点时间 :)
- 因为有时最好不要只使用另一个"魔术"包,而要了解幕后的情况:)
我只想添加
https://github.com/julienschmidt/httprouter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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!\ ") } func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { fmt.Fprintf(w,"hello, %s!\ ", ps.ByName("name")) } func main() { router := httprouter.New() router.GET("/", Index) router.GET("/hello/:name", Hello) log.Fatal(http.ListenAndServe(":8080", router)) } |
它似乎比
https://github.com/julienschmidt/go-http-routing-benchmark
这是一个如何使用@evanshaw中的代码示例的示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | func handleDigits(res http.ResponseWriter, req *http.Request) { res.Write([]byte("Digits in the URL\ ")) } func handleStrings(res http.ResponseWriter, req *http.Request) { res.Write([]byte("Strings in the URL\ ")) } func main() { handler := &RegexpHandler{} reg1, _ := regexp.Compile("/foo-\\\\d+") handler.HandleFunc(reg1, handleDigits) reg2, _ := regexp.Compile("/foo-\\\\w+") handler.HandleFunc(reg2, handleStrings) http.ListenAndServe(":3000", handler) } |
您可以检查violetear如何处理动态+综合(通配符)模式,这仅是补充示例:
1 2 3 | uuid := `[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}` router.AddRegex(":uuid") router.HandleFunc("/test/:uuid/:uuid", handleUUID,"GET,HEAD") |
在这种情况下,请求可能有2个不同的
对于动态/通配符,可以应用:
1 2 3 4 5 | http://api.violetear.org/command/ping/127.0.0.1 \\______/\\___/\\________/ | | | static | dynamic |
正则表达式可用于匹配IP:
1 2 | router.AddRegex(":ip", `^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$`) router.HandleFunc("/command/ping/:ip", ipHandler,"GET") |
或者只是简单地捕获所有只允许
1 | router.HandleFunc("/command/ping/*", anyHandler,"GET, HEAD") |
可以在这里找到更多示例:https://violetear.org/post/how-it-works/
Beego,所有Golang Web服务器问题的答案。 Wetalk是一个基于Beego的博客网站。
- https://github.com/astaxie/beego
- https://github.com/beego/wetalk
- "尽管此链接可以回答问题,但最好在此处包括答案的基本部分并提供链接以供参考。仅链接的答案可能会在链接页面更改时失效。"