简体   繁体   中英

multiple grails url mappings

In my Grails app, I have the following controller & action

class FestivalController {

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

I would like all of the following URLs to map to this controller

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

where glastonbury and music are the name and type of the festival respectively. Notice that only the ID (1) is actually needed to identify the festival, so the name and type are included in the URL for reasons of SEO and readability (of the URLs).

I attempted to support these different URLs with the following URL mappings

// 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 {           
    }
}

These support the 1st and 3rd URL mappings, but if I try the 2nd

/festival/show/1/glastonbury

it doesn't work. Ideally, I would like Grails to always generate a URL of the form:

/1/music/glastonbury

when I use g.createLink or g.link , but I would also like the following URLs to map to this action (for historical reasons):

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

Without seeing your other mapping rules it's hard to know what's relevant and what isn't... The behaviour you're seeing is inconsistent with the usual precedence rules, which I extracted from the source a while back and which say that when two mappings could apply to the same incoming URI, the one that wins is the one that has:

  1. Fewer double wildcards ( ** or $var** ), or if both are equal then
  2. Fewer single wildcards ( * or $var ), or if both are equal then
  3. More non-wildcard path segments, or if both are equal then
  4. The furthest left wildcard ( /foo/*/baz beats /foo/bar/* ), or if both have their leftmost wildcard in the same place then
  5. The one with more constraints

By these rules, /festival/show/1/glastonbury matches only the second mapping, so should work correctly, but /festival/show/1 matches both, so should be picked up by /$id/$type/$name (fewer wildcards), resulting in [controller:'festival', action:'show', id:'festival', type:'show', name:'1'] .

Adding an explicit rule for "/festival/$action?/$id?/$name?"(controller:'festival') should fix things as /festival/show/1 will match both this mapping and the /id/type/name one, but the explicit /festival/... mapping has more non-wildcard path segments (1 vs none).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM