Grails中的UrlMapping
>幾乎每種web服務都提供兩種風格的路由:__CGI風格__與__REST__風格
>CGI: `http://example/user/張三`
>REST:`http://example/user?name=張三`
>一目了然,上面就列出了這兩種風格的差異,當然也可以混用
Grails中也支持這些路由風格,雖然強調慣例優于配置,但在實際中總避免不了對uri路由地址進行精確控制,它的定義如下
class UrlMappings {
static mappings = {
//定義與此
}
}
__具體URL的映射語法例子如下__:
* 全格式:`"/product" (controller:"product", action:"list")`
* 使用缺省Action:`"/product" (controller:"product")`
* 使用閉包:
"/product" {
controller = "product"
action = "list"
}
* 將URI映射到另一個URI,常在與其他框架集成時用:`"/hello" (uri:"/hello.dispatch")`
__在映射語法中我們還可以使用變量,它們以 *$* 開頭,變量值會自動進入`params`,這樣在對應的action中就可以通過`“params.變量名”`訪問:__
* params.id:`"/product/$id" (...)`。如“/product/1”,其中1就是id的值,通過params.id即可訪問。
* 多個變量:`"/$blog/$year/$month/$day/$id"`。如`“/graemerocher/2007/01/10/my_funky_blog_entry”`,其中blog的值是graemerocher,year的值是2007,month的值是01,依次類推。
__利用變量,我們還可以動態構造Controller和Action的名字:__
* `“/$controller/$action?/$id?” ()`,通過params中的變量名得到Controller和Action的名字。
* 同樣,我們也可以通過閉包來實現:
"/$controller" {
action = { params.goHere }
}
__URL映射語法中同樣還支持可選參數,規則很簡單,在變量名后面加?即可。如上例的*“$id?”*。跟Java中的一樣,可選參數必須位于最后,形如`“/…/$變量名?/$變量名/$變量名?”`是不行的,但是`“/…/$變量名/$變量名?/$變量名?”`是可以的。__
定義變量也不一定非要在URL上進行,還可以在閉包中定義,如:
//傳遞任意值
"/holiday/win" {
id = "Marrakech"
year = 2007
}
//動態計算
"/holiday/win" {
id = { params.id }
isEligible = { session.user != null }
}
__上述例子都是演示的是如何把URL映射到Controller的Action,我們同樣可以把它映射到View:__
* 將root url映射到grails-app/views/index.gsp:`"/" (view:"/index")`
* 映射到某Controller的View:`"/help" (controller:"site",view:"help")`
__對于Http響應碼,我們也同樣可以進行映射,這樣我們就可以顯示更友好的錯誤信息界面,而不是單調的應用服務器相關的錯誤頁面了:__
* 把響應碼映射到Controller:`"500" (controller:"errors", action:"serverError")`
* 把響應碼映射到View:`"500" (view:"/errors/serverError")`
__URL映射還可以映射Http的方法,這在定義Restful Api的時候非常有用:__
static mappings = {
"/product/$id" (controller:"product"){
action = [GET:"show", PUT:"update",
DELETE:"delete", POST:"save"]
}
}
__Grails還支持在映射中使用通配符:__
* `"/images/*.jpg"(controllers:"image")`
* `"/images/$name.jpg"(controllers:"image")`,效果同上,不同的是使用了變量名。
* 同樣還可以使用**來映射多級目錄:`"/images/**.jpg"(controllers:"image")`
* 更好的一種方式則是:`"/images/$name**.jpg"(controllers:"image")`,這樣匹配的路徑會放到params.name中。
__在映射中我們還可以指定哪些URL不參與映射,在UrlMappings.groovy中靜態熟悉excludes中定義即可:__
class UrlMappings = {
static excludes = ["/images/**", "/css/**"] //排除
static mappings = {
...
}
}
Grails的URL映射還支持鏈接的自動重寫。如對于映射:`"/$blog/$year?/$month?/$day?/$id?"(controller:"blog", action:"show")`,以下的Link:
My Blog
My Blog - October 2007 Posts
產生結果:
My Blog
My Blog - October 2007 Posts
避免了直接使用URL,使得鏈接的定義和使用更靈活。
__在前面的文章中我們已經領略到了contraints的好處,對于URL映射,你同樣可以使用它,以驗證URL的有效性(正則):__
"/$blog/$year?/$month?/$day?/$id?" {
controller = "blog"
action = "show"
constraints {
year(matches:/d{4}/)
month(matches:/d{2}/)
day(matches:/d{2}/)
}
}
結果:
*有效*:/graemerocher/2007/01/10/my_funky_blog_entry
*無效*:/graemerocher/2007/01/101/my_funky_blog_entry
__對于映射,我們還可以給它起個名字,這就是命名映射的由來。語法:`name : {...}`。例子如下:__
static mappings = {
name personList: "/showPeople" {
controller = 'person'
action = 'list'
}
name accountDetails: "/details/$acctNumber" {
controller = 'product'
action = 'accountDetails'
}
}
使用時引用名字即可:
List People
Show Account
還可以使用``來使用,以上例子則變成:
List People
Show Account
浙公網安備 33010602011771號