(Quick Reference)

6.1.1 理解控制器和操作 - Reference Documentation

Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith

Version: null

6.1.1 理解控制器和操作

Creating a controller

Controllers can be created with the create-controller or generate-controller command. For example try running the following command from the root of a Grails project:

grails create-controller book

The command will create a controller at the location grails-app/controllers/myapp/BookController.groovy:

package myapp

class BookController {

def index() { } }

where "myapp" will be the name of your application, the default package name if one isn't specified.

BookController by default maps to the /book URI (relative to your application root).

The create-controller and generate-controller commands are just for convenience and you can just as easily create controllers using your favorite text editor or IDE

创建控制器

控制器可以通过create-controller或者generate-controller命令创建。比如,在Grails工程的根目录中运行如下命令:

grails create-controller book

此命令将创建一个位于grails-app/controllers/myapp/BookController.groovy的控制器:

package myapp

class BookController {

def index() { } }

此处"myapp"是你应用的名称,如果你没有指定包名的话,缺省的包名就是应用名称。

BookController缺省被映射于URI /book (相对于你应用上下文的根而言)

create-controllergenerate-controller命令只是便利方法而已,你也可以使用你喜欢的文本编辑器或者IDE来轻松的创建控制器。

Creating Actions

A controller can have multiple public action methods; each one maps to a URI:

class BookController {

def list() {

// do controller logic // create model

return model } }

This example maps to the /book/list URI by default thanks to the property being named list.

创建操作

一个控制器可以有多个公共操作方法,每一个都映射于一个URI:

class BookController {

def list() {

// do controller logic // create model

return model } }

缺省情况下,这个示例将映射到URI /book/list,这要归功于list属性。

Public Methods as Actions

In earlier versions of Grails actions were implemented with Closures. This is still supported, but the preferred approach is to use methods.

Leveraging methods instead of Closure properties has some advantages:

  • Memory efficient
  • Allow use of stateless controllers (singleton scope)
  • You can override actions from subclasses and call the overridden superclass method with super.actionName()
  • Methods can be intercepted with standard proxying mechanisms, something that is complicated to do with Closures since they're fields.

If you prefer the Closure syntax or have older controller classes created in earlier versions of Grails and still want the advantages of using methods, you can set the grails.compile.artefacts.closures.convert property to true in BuildConfig.groovy:

grails.compile.artefacts.closures.convert = true

and a compile-time AST transformation will convert your Closures to methods in the generated bytecode.

If a controller class extends some other class which is not defined under the grails-app/controllers/ directory, methods inherited from that class are not converted to controller actions. If the intent is to expose those inherited methods as controller actions the methods may be overridden in the subclass and the subclass method may invoke the method in the super class.

公共方法作为操作

在以前版本的Grails中,操作是通过闭包来实现的。现在依然是支持的,不过更推荐使用方法的方式来实现。

使用方法来替代闭包有如下一些优点:

  • 更高效的内存
  • 允许使用状态无关的控制器(作用域是singleton
  • 你可以在子类中重载操作,并且可以使用super.actionName()调用父类的方法
  • 方法可以通过标准的代理机制进行拦截,同样的事情闭包更复杂一些,因为它们是属性字段。

如果你更喜欢闭包的语法或者现有的控制器类是以前版本的Grails所创建的,又想得到方法作为操作的好处,你可以设置BuildConfig.groovy中的grails.compile.artefacts.closures.convert属性为true:

grails.compile.artefacts.closures.convert = true

这时,一个编译时的AST变换会在生成字节码的时候,将你的闭包转变为方法

如果一个控制器类继承于其他类,但不是被定义在grails-app/controllers/目录下,那么继承过来的方法将不会被转换成控制器操作的。如果目标是为了能将那些继承来的方法暴露为控制器操作,那么这些方法应该是能够被子类重载的,并且在子类中也可以调用其父类的方法。

The Default Action

A controller has the concept of a default URI that maps to the root URI of the controller, for example /book for BookController. The action that is called when the default URI is requested is dictated by the following rules:

  • If there is only one action, it's the default
  • If you have an action named index, it's the default
  • Alternatively you can set it explicitly with the defaultAction property:

static defaultAction = "list"

缺省操作

一个控制器即映射到控制器的根URI。默认情况下缺省URI在这里的是/book。默认的URI通过以下规则来支配: 一个控制器具有默认URI的概念,其将映射到控制器的根URI。比如BookController映射到/book。当缺省URI被请求时,会根据以下规则来调用操作:

  • 如果仅有一个操作,那么它就是那个缺省操作
  • 如果你有一个index操作,那么它就是缺省的
  • 或者你可以使用defaultAction属性来明确指定:

static defaultAction = "list"