Golang中如何像gorilla/mux路由器那样匹配URL模式的字符串
Golang中如何像gorilla/mux路由器那样匹配URL模式的字符串 基本上我有这段代码:
package main
import (
"github.com/gorilla/mux"
[...]
)
func main(){
[...]
router := mux.NewRouter()
router.HandleFunc("/", handler.ViewAllPosts).Methods(http.MethodGet)
router.HandleFunc("/events", handler.ViewEvents).Methods(http.MethodGet)
router.HandleFunc("/about", handler.ViewAbout).Methods(http.MethodGet)
router.HandleFunc("/blog/{URLTitle}", handler.ViewPost).Methods(http.MethodGet)
[...]
}
我想做类似这样的事情:
switch urlStringVar {
case "/":
fmt.Println("ViewAllPosts")
case "/events":
fmt.Println("ViewEvents")
case "/about":
fmt.Println("ViewAbout")
case "/blog/{URLTitle}":
fmt.Println("ViewPost")
}
细节(如果可能的话)是它必须与 “gorilla/mux” 的匹配方式完全相同,有没有办法实现这一点?或者你推荐其他什么选项?
更多关于Golang中如何像gorilla/mux路由器那样匹配URL模式的字符串的实战教程也可以访问 https://www.itying.com/category-94-b0.html
@ Sibert
这个我能做到,我的问题在于通配符:
case "/blog/{URLTitle}":
更多关于Golang中如何像gorilla/mux路由器那样匹配URL模式的字符串的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Willy:
有什么方法可以实现这一点吗?或者你推荐其他什么选项?
对于单层结构来说,这很简单。我还没有测试过多层结构。但是你可以从这里获取一些提示。
另一种选择是查看 julienschmidt/httprouter 的代码。它仅仅是一个路由器,并且代码行数比 gorilla/mux 少得多。可能更容易理解其中的关键部分。
查看 gorilla/mux 的代码。
// Copyright 2012 The Gorilla Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package mux
import (
"bytes"
"fmt"
"net/http"
"net/url"
"regexp"
"strconv"
"strings"
)
type routeRegexpOptions struct {
strictSlash bool
useEncodedPath bool
}
Willy:
这个我能做到,我的问题在于通配符:
你可以使用这个函数来提取URL路径中向下两级的部分(通配符)(在这个例子中)。这可能需要额外的代码才能完全实现功能。
func getpath(r *http.Request) (string, string) {
path := strings.Split(r.URL.String(), "/")
switch len(path) {
case 2:
return path[1], "", ""
default:
return "", "", ""
}
}
伪代码:
path1, path2 = getpath(r)
switch levels {
case path2='':
Open page path1
default:
Open page "blog/" + path2
}
if page not exist open 404.html
这减少了条件判断的层级。
可以使用 gorilla/mux 的 Path 和 Match 方法来实现与路由器相同的URL模式匹配。以下是一个示例:
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
// 创建路由器并定义路由
router := mux.NewRouter()
router.Path("/").Methods(http.MethodGet)
router.Path("/events").Methods(http.MethodGet)
router.Path("/about").Methods(http.MethodGet)
router.Path("/blog/{URLTitle}").Methods(http.MethodGet)
// 要测试的URL路径
testPaths := []string{
"/",
"/events",
"/about",
"/blog/my-first-post",
"/blog/another-post",
"/invalid",
}
// 匹配每个路径
for _, path := range testPaths {
var match mux.RouteMatch
request, _ := http.NewRequest("GET", path, nil)
if router.Match(request, &match) {
routePath, _ := match.Route.GetPathTemplate()
vars := match.Vars
fmt.Printf("路径: %s\n", path)
fmt.Printf(" 匹配路由: %s\n", routePath)
if len(vars) > 0 {
fmt.Printf(" 路径变量: %v\n", vars)
}
// 根据匹配的路由执行相应操作
switch routePath {
case "/":
fmt.Println(" 执行: ViewAllPosts")
case "/events":
fmt.Println(" 执行: ViewEvents")
case "/about":
fmt.Println(" 执行: ViewAbout")
case "/blog/{URLTitle}":
fmt.Println(" 执行: ViewPost")
fmt.Printf(" 文章标题: %s\n", vars["URLTitle"])
}
} else {
fmt.Printf("路径: %s - 未匹配任何路由\n", path)
}
fmt.Println()
}
}
输出示例:
路径: /
匹配路由: /
执行: ViewAllPosts
路径: /events
匹配路由: /events
执行: ViewEvents
路径: /about
匹配路由: /about
执行: ViewAbout
路径: /blog/my-first-post
匹配路由: /blog/{URLTitle}
执行: ViewPost
文章标题: my-first-post
路径: /blog/another-post
匹配路由: /blog/{URLTitle}
执行: ViewPost
文章标题: another-post
路径: /invalid - 未匹配任何路由
如果需要更简洁的封装,可以创建一个匹配函数:
func matchPath(router *mux.Router, path string) (string, map[string]string, bool) {
var match mux.RouteMatch
request, _ := http.NewRequest("GET", path, nil)
if router.Match(request, &match) {
routePath, _ := match.Route.GetPathTemplate()
return routePath, match.Vars, true
}
return "", nil, false
}
// 使用示例
func handleURL(path string) {
router := mux.NewRouter()
router.Path("/").Methods(http.MethodGet)
router.Path("/events").Methods(http.MethodGet)
router.Path("/about").Methods(http.MethodGet)
router.Path("/blog/{URLTitle}").Methods(http.MethodGet)
if routePath, vars, matched := matchPath(router, path); matched {
switch routePath {
case "/":
fmt.Println("ViewAllPosts")
case "/events":
fmt.Println("ViewEvents")
case "/about":
fmt.Println("ViewAbout")
case "/blog/{URLTitle}":
fmt.Printf("ViewPost - Title: %s\n", vars["URLTitle"])
}
} else {
fmt.Println("No match found")
}
}
这种方法直接使用 gorilla/mux 的路由匹配引擎,确保与路由器本身的匹配行为完全一致。

