现在的位置: 首页 > 综合 > 正文

Grails中的UrlMapping

2012年10月10日 ⁄ 综合 ⁄ 共 2857字 ⁄ 字号 评论关闭
>几乎每种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

避免了直接使用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 PeopleShow Account
【上篇】
【下篇】

抱歉!评论已关闭.