Revel路由正则参数必须用{name}格式,如{id},不可省略尖括号或混用gorilla/mux或Martini风格写法。

Revel 路由中正则参数的写法必须用 {<pattern>name}</pattern> 格式
Revel 不支持 Gorilla 那种 /hotels/{id:[0-9]+} 的内联正则写法,也不接受 :id 或 :id\d+ 这类 Martini 风格。它的正则必须包裹在尖括号里,且紧贴花括号内部,格式固定为 {参数名}。漏掉任一符号(如少 、多空格、括号错位)都会导致路由不匹配,但不会报错——请求直接 404。
常见错误现象包括:
- 写了
/user/{id:[0-9]+}→ 不生效,当成字面量路径处理 - 写了
/user/{id}→ 编译失败或 panic(反斜杠未转义) - 写了
/user/{id}→ 多了空格,解析失败,静默忽略该路由
正确写法示例:GET /users/{id} Users.Show,它只匹配 /users/123,不匹配 /users/abc 或 /users/123abc。
conf/routes 里正则必须能被 Go 的 regexp 包编译
Revel 底层调用的是 Go 标准库的 regexp.Compile,所以你写的正则必须是合法的 Go 正则语法。比如不能用 JavaScript 风格的 d(需写成 [0-9]),也不能用 PCRE 的 \K 或条件断言。最稳妥的是只用字符类、量词和分组。
推荐用法:
- 数字 ID:
{id} - UUID(带连字符):
{uuid} - 字母+数字混合(如 slug):
{slug}
注意:Revel 会自动在你写的正则前后加上 ^ 和 $,所以不需要自己加锚点;也不支持 .* 开头的贪婪匹配——它默认只匹配单个路径段(即不跨 /)。
参数提取时类型转换要手动做,Params.Bind 不支持正则校验
即使你在路由里写了 {id},Revel 也只负责「匹配」和「提取字符串」,不会自动转成 int。如果你在 action 方法签名里写 func (c Users) Show(id int),而实际 URL 是 /users/abc(绕过正则?不可能,已 404),但万一正则写得宽泛(比如 {id}),那 id 就是字符串,强制转 int 会 panic。
安全做法是:
- 始终用
c.Params.Get("id")拿原始字符串 - 用
strconv.Atoi或uuid.Parse显式转换,并检查 error - 不要依赖
Params.Bind("id", reflect.TypeOf(0))做自动转换——它不读取路由正则,只按类型尝试 parse,失败就返回零值,容易掩盖问题
例如:
func (c Users) Show() revel.Result {<br> idStr := c.Params.Get("id")<br> id, err := strconv.Atoi(idStr)<br> if err != nil {<br> return c.RenderError("invalid id format")<br> }<br> // ...<br>}
通配符 {*wildcard} 和正则不能混用,且不支持嵌套
Revel 支持通配符写法 /files/{*path},但它和正则参数是互斥机制:一个路径段里不能同时有 {<...>name}</...> 和 {*name}。而且 {*path} 会吃掉从当前位置到 URL 结尾的所有内容(含多个 /),它本身不支持正则限定——你没法写 {*path}。
如果需要「限制通配部分的格式」,只能靠 handler 里手动校验 c.Params.Get("path") 字符串,比如检查是否只含小写字母、数字和斜线,再拒绝非法路径。
容易被忽略的一点:通配符必须是路径最后一段,比如 /static/{*file} 合法,但 /static/{*file}/meta 会解析失败——Revel 不支持通配后接其他静态路径。











