0

在我的 Grails 应用程序中,我有以下控制器和操作

class FestivalController {

  def show() {
    [festival: Festival.get(params.id)]
  }
}

我希望以下所有 URL 都映射到此控制器

/festival/show/1
/festival/show/1/glastonbury
/1/music/glastonbury

whereglastonburymusic分别是节日的名称和类型。请注意,实际上只需要 ID (1) 来识别节日,因此出于 SEO 和(URL 的)可读性的原因,名称和类型包含在 URL 中。

我尝试使用以下 URL 映射来支持这些不同的 URL

// this supports the 3rd mapping above
name showFestival: "/$id/$type?/$name?" {
    controller = "festival"
    action = "show"
}

// this supports the 1st mapping above
"/$controller/$action?/$id?/$name?"{
    constraints {           
    }
}

这些支持第一个和第三个 URL 映射,但如果我尝试第二个

/festival/show/1/glastonbury

它不起作用。理想情况下,我希望 Grails 始终生成以下形式的 URL:

/1/music/glastonbury

当我使用g.createLinkor时g.link,但我还希望以下 URL 映射到此操作(出于历史原因):

/festival/show/1
/festival/show/1/glastonbury
4

1 回答 1

3

没有看到你的其他映射规则,很难知道什么是相关的,什么是不相关的......你看到的行为与通常的优先规则不一致,我不久前从源中提取了它,它说当两个映射可以应用于相同的传入 URI,获胜的是具有以下内容的 URI:

  1. 更少的双通配符(**$var**),或者如果两者相等,则
  2. 更少的单个通配符(*$var),或者如果两者相等,则
  3. 更多非通配符路径段,或者如果两者相等,则
  4. 最左边的通配符(/foo/*/bazbeats /foo/bar/*),或者如果它们的最左边的通配符在同一个地方,那么
  5. 一个拥有更多constraints

根据这些规则,/festival/show/1/glastonbury仅匹配第二个映射,因此应该可以正常工作,但同时/festival/show/1匹配两者,因此应该被(更少的通配符)拾取/$id/$type/$name,从而导致[controller:'festival', action:'show', id:'festival', type:'show', name:'1'].

添加一个明确的规则"/festival/$action?/$id?/$name?"(controller:'festival')应该解决问题,因为/festival/show/1这将匹配这个映射和/id/type/name一个,但是明确的/festival/...映射有更多的非通配符路径段(1 vs none)。

于 2012-08-31T11:45:43.307 回答