重定向与路由匹配优先级
理解 Gin 路由匹配规则对正确配置路由至关重要。
匹配优先级规则
Gin 基于 httprouter,遵循以下匹配优先级:
| 优先级 | 规则类型 | 示例 |
|---|---|---|
| 1 | 精确匹配 | /user/profile |
| 2 | 参数匹配 | /user/:id |
| 3 | 通配符匹配 | /user/*action |
精确匹配优先
Go
r.GET("/user/profile", func(c *gin.Context) {
c.String(200, "精确匹配: profile")
})
r.GET("/user/:id", func(c *gin.Context) {
c.String(200, "参数匹配: id=%s", c.Param("id"))
})
// GET /user/profile → 输出: 精确匹配: profile
// GET /user/123 → 输出: 参数匹配: id=123
通配符匹配
* 通配符可匹配剩余所有路径:
Go
r.GET("/files/*filepath", func(c *gin.Context) {
filepath := c.Param("filepath") // 包含前导 /
c.String(200, "文件路径: %s", filepath)
})
// GET /files/path/to/file.txt → filepath = /path/to/file.txt
// GET /files/ → filepath = /
冲突路由
以下配置会产生冲突:
Go
// 错误示例:参数名相同会产生冲突
r.GET("/user/:id", handler1)
r.GET("/user/:id/profile", handler2) // 冲突!
// 正确做法
r.GET("/user/:id", handler1)
r.GET("/user/:id/*action", handler2) // 使用通配符区分
路由重定向行为
Gin 默认对路径末尾斜杠有特殊处理:
Go
r.GET("/user", func(c *gin.Context) {
c.String(200, "user")
})
// GET /user → 200 OK
// GET /user/ → 301 重定向到 /user
禁用自动重定向
Go
r := gin.New()
r.RedirectTrailingSlash = false // 禁用末尾斜杠重定向
r.RedirectFixedPath = false // 禁用路径修正重定向
路由组匹配
路由组继承基础路径:
Go
api := r.Group("/api")
{
api.GET("/users", listUsers) // /api/users
api.GET("/users/:id", getUser) // /api/users/:id
api.POST("/users", createUser) // /api/users
}
// 内部优先级相同,精确优先
匹配示例
Go
r.GET("/a", func(c *gin.Context) {
c.String(200, "a")
})
r.GET("/a/:id", func(c *gin.Context) {
c.String(200, "a/:id")
})
r.GET("/a/*filepath", func(c *gin.Context) {
c.String(200, "a/*filepath")
})
r.GET("/a/b/c", func(c *gin.Context) {
c.String(200, "a/b/c")
})
| 请求路径 | 匹配结果 |
|---|---|
/a | a (精确) |
/a/123 | a/:id (参数) |
/a/b/c | a/b/c (精确优先) |
/a/b/c/d | a/*filepath (通配符) |
/a/b | a/:id (参数匹配) |
路由定义时注意精确匹配和参数匹配的顺序,避免意外匹配。
要点总结
- 精确匹配优先级最高,参数匹配其次,通配符最低
*通配符可匹配剩余全部路径- 相同位置的参数名必须唯一,否则冲突
- Gin 默认对路径末尾斜杠自动重定向
- 可通过配置禁用自动重定向行为
📝 发现内容有误?点击此处直接编辑