Grails WEB层 URL映射

 

6.4 URL映射

到目前为止,贯穿整个文档用于URLs的规约默认为 /controller/action/id . 然而,这个规约不是硬性的写入Grails中,实际上,它是通过一个位于 grails-app/conf/UrlMappings.groovy 的URL映射类所控制.

UrlMappings类包含一个名为mappings单一属性,并被赋予一个代码块:

 

class UrlMappings {
    static mappings = {
    }	
}

 

6.4.1 映射到控制器和操作

为了创建简单的映射,只需简单的使用相对URL作为方法名,并指定控制器和操作的命名参数来映射:

 

"/product"(controller:"product", action:"list")

在这种情况下,我们建立URL/productProductControllerlist操作的映射。你当然可以省略操作定义,来映射控制器默认的操作:

 

"/product"(controller:"product")

一个可选的语法是把在块中被赋值的控制器和操作传递给方法:

 

"/product" {
	controller = "product"
	action = "list"
}

你使用哪一个句法很大程度上依赖于个人偏好.

 

6.4.2 嵌入式变量

简单变量

早前的部分说明,怎样使用具体的"标记"来映射普通的URLs。在URL映射里讲过,标记是在每个斜线(/)字符之间的顺序字符。 一个具体的标记就像/product这样被良好定义。然而,很多情况下,标记的值直到运行时才知道是什么。在这种情况下,你可以在URL中使用变量占位符,例如:

 

static mappings = {
  "/product/$id"(controller:"product")
}

在这种情况下,通过嵌入一个$id变量作为第2个标记,Grails将自动映射第2个标记到一个名为id的参数(通过params对象得到). 例如给定的URL/product/MacBook,下面的代码将渲染"MacBook"到响应中:

 

class ProductController {
     def index = { render params.id }
}

当然你可以构建更多复杂的映射示例。例如传统的blog URL格式将被映射成下面这样:

 

static mappings = {
   "/$blog/$year/$month/$day/$id"(controller:"blog", action:"show")
}

上面的映射允许你这样:

 

/graemerocher/2007/01/10/my_funky_blog_entry

在URL里单独的标记将再次被映射到带有year, month, day, id等等可用值的 params 对象中.

 

动态控制器(Controller)和操作(Action)名

变量同样可以被用于动态构造控制器和操作名。实际上,默认的Grails URL映射使用这样的技术:

 

static mappings = {
    "/$controller/$action?/$id?"()
}

这里,控制器(controller)名,操作(action)名和id名,隐式的从嵌入在URL中的controller, actionid中获得:

 

static mappings = {
    "/$controller" {
	   action = { params.goHere }
    }
}

 

可选的变量

默认映射另一个特性就是能够在一个变量的末尾附加一个? ,使它成为一个可选的标记。这个技术更进一步的示例能够运用于blog URL映射,使它具有更灵活性的连接 :

 

static mappings = {
   "/$blog/$year?/$month?/$day?/$id?"(controller:"blog", action:"show")
}

下列URLs的所有映射将与放置于params对象中的唯一关联的参数匹配:

 

/graemerocher/2007/01/10/my_funky_blog_entry
/graemerocher/2007/01/10
/graemerocher/2007/01
/graemerocher/2007
/graemerocher

 

任意变量

你同样可以传递来自于URL映射的任意参数给控制器,把他们设置在块内传递给这个映射:

 

"/holiday/win" {
     id = "Marrakech"
     year = 2007
}

在这个params对象得到的这个变量将被传递给这个控制器.

 

动态解析变量

硬编码任意变量是有用的,但是,有时你需要基于运行时因素来计算变量名。这个同样可能通过给变量名分配一个块:

 

"/holiday/win" {
     id = { params.id } 
     isEligible = { session.user != null } // must be logged in
}

上述情况,当URL实际被匹配,块中的代码将被解析,因此可以被用于结合所有种类的逻辑处理.

6.4.3 映射到视图

如果你想决定一个URL一个view,而无需涉及一个控制器或者操作,你也可以这样做。 例如,如果你想映射根URL / 到一个位于 grails-app/views/index.gsp 的GSP,你可以这样使用:

 

static mappings = {
      "/"(view:"/index")  // map the root URL
}

换句话说,假如你需要一个具体给定的控制器(Controller)中的一个视图,你可以这样使用:

 

static mappings = {
   "/help"(controller:"site",view:"help") // to a view for a controller
}

6.4.4 映射到响应代码

Grails同样允许你映射一个HTTP响应代码到控制器,操作或视图。所有你需要做的是使用一个方法名来匹配你所感兴趣的响应代码:

 

static mappings = {
   "500"(controller:"errors", action:"serverError")
   "404"(controller:"errors", action:"notFound")
   "403"(controller:"errors", action:"forbidden")
}

或者换句话说,假如你只不过想提供定制的错误页面:

 

static mappings = {
   "500"(view:"/errors/serverError")
   "404"(view:"/errors/notFound")
   "403"(view:"/errors/forbidden")
}

6.4.5 映射到HTTP方法

URL映射同样可以配置成基于HTTP 方法 (GET, POST, PUT or DELETE)的map。这个对于RESTful APIs和基于HTTP方法的约束映射是非常有用的.

作为一个示例,下面的映射为ProductControllerURL提供一个RESTful API URL映射:

 

static mappings = {
   "/product/$id"(controller:"product"){
       action = [GET:"show", PUT:"update", DELETE:"delete", POST:"save"]
   }	
}

6.4.6 映射通配符

Grails的URL映射机制同样支持通配符映射。例如,考虑下面的映射:

 

static mappings = {
	"/images/*.jpg"(controller:"image")
}

这个映射将匹配所有images路径下像/image/logo.jpg这样的jpg。当然你可以通过一个变量来达到同样的效果:

 

static mappings = {
	"/images/$name.jpg"(controller:"image")
}

然而,你可以使用双通配符来匹配多于一个层次之外的:

 

static mappings = {
	"/images/**.jpg"(controller:"image")
}

这样的话,这个映射将不但匹配/image/logo.jpg而且匹配/image/other/logo.jpg。更好的是你可以使用一个双通配符变量:

 

static mappings = {
	// will match /image/logo.jpg and /image/other/logo.jpg 
	"/images/$name**.jpg"(controller:"image")
}

这样的话,它将储存路径,从params 对象获得命名参数里的name通配符 :

 

def name = params.name
println name // prints "logo" or "other/logo"

如果你使用通配符URL mappings,那么你可以排除某些来自Grails的URL mapping进程 URIs. 实现这个你可以在UrlMappings.groovy类中设置excludes :

 

class UrlMappings = {
	static excludes = ["/images/**", "/css/**"]
	static mappings = {
		…
	}
}

这样,Grails不为匹配任何以 /images/css开头的URLs.

 

6.4.7 自动重写链接

URL映射另一个重要的特性是自动定制 link 标签的行为。以便改变这个映射而不需要改变所有的连接.

通过一个URL重写技术做到这点,从URL映射反转连接设计:

 

static mappings = {
   "/$blog/$year?/$month?/$day?/$id?"(controller:"blog", action:"show")
}

如果,你像下列一样使用连接标签:

 

<g:link controller="blog" action="show" params="[blog:'fred', year:2007]">My Blog</g:link>
<g:link controller="blog" action="show" params="[blog:'fred', year:2007, month:10]">My Blog - October 2007 Posts</g:link>

Grails将自动重写URL通过适当的格式:

 

<a href="/fred/2007">My Blog</a>
<a href="/fred/2007/10">My Blog - October 2007 Posts</a>

6.4.8 应用约束

URL映射同样支持Grails统一 验证规约 机制, 它允许你更进一步"约束"一个URL是怎么被匹配的。例如,如果我们回到早前的blog示例代码,这个映射当前看上去会像这样 :

 

static mappings = {
   "/$blog/$year?/$month?/$day?/$id?"(controller:"blog", action:"show")
}

允许URLs像这样:

 

/graemerocher/2007/01/10/my_funky_blog_entry

不过,它也允许这样:

 

/graemerocher/not_a_year/not_a_month/not_a_day/my_funky_blog_entry

当它强迫你在控制器代码中做一些聪明的语法分析时会有问题。幸运的是,URL映射能进一步的约束验证URL标记:

 

"/$blog/$year?/$month?/$day?/$id?" {
     controller = "blog"
     action = "show"
     constraints {
          year(matches:/d{4}/)
          month(matches:/d{2}/)
          day(matches:/d{2}/)
     }
}

在这种情况下,约束能确保 year, monthday参数匹配一个具体有效的模式,从而在稍后来减轻你的负担 . 

你可能感兴趣的:(Web,Blog,嵌入式,grails,groovy)