4

我昨天搞砸了这个,惨遭失败。我想转换:

"/$controller/$action?/$id?"

#in psudo
"/$controller/$id?/$action?"
#ideal regex
"\/(\w+)(\/\d+)?(\/\w+)?" 

最明显的方法失败了"/$controller/$action?/$id?"

我可以编写正则表达式来做到这一点,但我无法找到使用真正正则表达式的方法(我找到了RegexUrlMapping但找不到如何使用它),也找不到有关如何分配组的文档一个变量。

我的问题是两部分:

  1. 如何使用真正的正则表达式定义 URL 资源。
  2. 如何将“组”绑定到变量。换句话说,如果我定义一个正则表达式,我如何将它绑定到一个变量,如 $controller、$id、$action

我还希望能够支持 .json 表示法 /user/id.json


我尝试过的其他事情,我认为这会起作用:

"/$controller$id?$action?"{
        constraints {
            controller(matches:/\w+/)
            id(matches:/\/\d+/)
            action(matches:/\/\w+/)
        }
    }

也试过:

"/$controller/$id?/$action?"{
        constraints {
            controller(matches:/\w+/)
            id(matches:/\d+/)
            action(matches:/\w+/)
        }
    }
4

1 回答 1

2

解决这个问题的 grails 方法是设置

grails.mime.file.extensions = true

Config.groovy. 这将导致 Grails 在应用 URL 映射之前去除文件扩展名,但使其可供以下用户使用withFormat

def someAction() {
  withFormat {
    json {
      render ([message:"hello"] as JSON)
    }
    xml {
      render(contentType:'text/xml') {
        //...
      }
    }
  }

为此,您只需要一个 URL 映射"$controller/$id?/$action?"

我不知道在 URL 映射中以您希望的方式使用正则表达式的任何方法,但是您可以使用以下事实来获得正向映射工作,即您可以为在运行时评估的参数值指定闭包并访问其他参数:

"$controller/$a?/$b?" {
  action = { params.b ?: params.a }
  id = { params.b ? params.a : null }
}

它说“如果b已设置,则将其用作操作并a用作id,否则a用作操作并设置idnull”。但这不会给你一个很好的反向映射,即createLink(controller:'foo', action:'bar', id:1)不会产生任何合理的东西,你必须使用createLink(controller:'foo', params:[a:1, b:'bar'])

编辑

您可以尝试的第三种可能性是将

"/$controller/$id/$action"{
    constraints {
        controller(matches:/\w+/)
        id(matches:/\d+/)
        action(matches:/\w+/)
    }
}

映射与互补

"/$controller/$action?"{
    constraints {
        controller(matches:/\w+/)
        action(matches:/(?!\d+$)\w+/)
    }
}

使用负前瞻来确保两个映射不相交。

于 2013-02-21T16:50:52.457 回答