Play 2.0 中文资料 - Action, Controller 和 Result
什么是 Action?
多数的请求被 Play 应用接收到,并由
一个
Action 返回一个
建造一个 Action
最简单的一个方法是以返回值为
这是创建 Action 的最简单的方式, 但是我们无法得到传入的请求的引用. 通常调用 Action 的时候会要求访问 HTTP 请求.
因此,还有另外一个 Action 建造器,它接收一个函数
经常会用
最后一种创建 Action 值的方式是指定一个附加的
Body 解析器将会在本手册的后面讲到. 当前你仅需了解其他创建 Action 值的方法是使用了一个默认的任意内容请求数据体解析器 (Any content body parser).
Controller 是 action 的产生器
最简单的用于定义一个 Action 产生器的案例就是一个无参并返回 Action 值的方法:
当然了, Action 产生器方法也可以带参数, 这些参数能够被 Action 闭包捕获的到:
Unmi 注: 从 Action 开始要理解下 Scala 比较灵活的语法了。首先感性的知道下 Scala 方法定义的最主要四种形式是,不妨先记下它们来:
拿第二行来说明它的由来,它的完整的方法定义如下:
Unmi 注: Scala 把上面的写法转换成 def index Action { request => .......} 是基于以下几个规则的:
1. 如果定义的方法返回值不是 Unit 类型的话就必须要在方法实现之前加上等号
2. 如果方法实现只有一条语句,或者 Scala 能够推断出方法何时结束,则可以省略掉方法体外围的大括号,此处的 index 就是直接返回 Action 方法的值
3. 如果方法只有一个参数,则调用它时可以用花括号代替小括号包围参数,所以通常把 Action( request => ......) 写成了 Action{ request => ......}。这样写的好处就是它看起来像是一种内建控制结构。这里 request => ...... 是一个闭包,或称字面函数参数
4. 在 Action.scala 源文件中,Action 是一个单例对象:
直接在对象后加上括号的写法会转去调用它相应的 apply 方法,上面的 Action 继承了特质 ActionBuilder,而在特质 ActionBuilder 中定义了如下几个 apply 方法:
从这些源文件知道 Action 里是个闭包就行,返回是个 Result 类型。至于执行时 request 值是怎么产生的还需研究下。
简单的 Result
目前我们只讲述简单的 Result: 一个具有状态代码的 HTTP Result, 一系列 HTTP 头和要发送到 Web 客户端的响应体.
这些 Result 由
当然,也有数个帮助方法让你创建通用的 Result,像下面例子中的
这会产生与之上例中完全相同的 Result.
下面是几个创建种种 Result 的例子:
所有的这些帮助方法可在
重定向也是简单的 Result
重定向浏览器到一个新的 URL 是另一类简单的 Result. 然而, 这类 Result 类型不会带上响应体.
下面是些创建重定向 Result 的几个帮助方法:
默认是利用
Unmi 注: 返回 Result 类型的各方法定义在 Controller 所继承的 Results(.scala) 文件中,如 Ok,Redirect 等方法。
“TODO” 虚页面
你可以用一个定义为
Unmi 注: TODO 定义在 trait Controller(.scala) 中:
永久链接 https://yanbin.blog/play2-0-tutorials-cn-action-controller-result/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
多数的请求被 Play 应用接收到,并由
Action 进行处理.一个
play.api.mvc.Action 简单说来就是一个 (play.api.mvc.Request => play.api.mvc.Result) 函数,它处理请求并产生一个 result 发送给客户端.1val echo = Action { request =>
2 Ok("Got request [" + request + "]")
3}Action 返回一个
play.api.mvc.Result 值, 代表着发送给 Web 客户端的 HTTP 响应. 上面的例子中 Ok 构造了一个 200 OK 的响应,它包含了 text/plain 类型的响应体.建造一个 Action
play.api.mvc.Action 伴生对象提供有多个帮助方法用于构建 Action 值.最简单的一个方法是以返回值为
Result 的表达式块作为参数:1Action {
2 Ok("Hello world")
3}这是创建 Action 的最简单的方式, 但是我们无法得到传入的请求的引用. 通常调用 Action 的时候会要求访问 HTTP 请求.
因此,还有另外一个 Action 建造器,它接收一个函数
Request => Result 作为参数:1Action { request =>
2 Ok("Got request [" + request + "]")
3}经常会用
implicit 来标记 request 参数,这样可在其他的 API 需要的时候隐式的使用它:1Action { implicit request =>
2 Ok("Got request [" + request + "]")
3}最后一种创建 Action 值的方式是指定一个附加的
BodyParser 作为参数:1Action(parse.json) { implicit request =>
2 Ok("Got request [" + request + "]")
3}Body 解析器将会在本手册的后面讲到. 当前你仅需了解其他创建 Action 值的方法是使用了一个默认的任意内容请求数据体解析器 (Any content body parser).
Controller 是 action 的产生器
Controller 总是一个用来产生 Action 值的单例对象.最简单的用于定义一个 Action 产生器的案例就是一个无参并返回 Action 值的方法:
1package controllers
2
3import play.api.mvc._
4
5object Application extends Controller {
6
7 def index = Action {
8 Ok("It works!")
9 }
10
11}当然了, Action 产生器方法也可以带参数, 这些参数能够被 Action 闭包捕获的到:
1def hello(name: String) = Action {
2 Ok("Hello " + name)
3}Unmi 注: 从 Action 开始要理解下 Scala 比较灵活的语法了。首先感性的知道下 Scala 方法定义的最主要四种形式是,不妨先记下它们来:
1def index = Action { ...... } //不访问 request
2def index = Action { request => ...... } //代码块中要访问 request
3def index = Action(parse.json) { ...... } //这是调用了柯里化(currying) 后的函数
4def index(name: String) = Action { ...... } //获得请求参数 name拿第二行来说明它的由来,它的完整的方法定义如下:
1def index = {
2 Action( request =>
3 ......
4 )
5}Unmi 注: Scala 把上面的写法转换成 def index Action { request => .......} 是基于以下几个规则的:
1. 如果定义的方法返回值不是 Unit 类型的话就必须要在方法实现之前加上等号
2. 如果方法实现只有一条语句,或者 Scala 能够推断出方法何时结束,则可以省略掉方法体外围的大括号,此处的 index 就是直接返回 Action 方法的值
3. 如果方法只有一个参数,则调用它时可以用花括号代替小括号包围参数,所以通常把 Action( request => ......) 写成了 Action{ request => ......}。这样写的好处就是它看起来像是一种内建控制结构。这里 request => ...... 是一个闭包,或称字面函数参数
4. 在 Action.scala 源文件中,Action 是一个单例对象:
1/**
2 * Helper object to create `Action` values.
3 */
4object Action extends ActionBuilder直接在对象后加上括号的写法会转去调用它相应的 apply 方法,上面的 Action 继承了特质 ActionBuilder,而在特质 ActionBuilder 中定义了如下几个 apply 方法:
1/**
2 * Provides helpers for creating `Action` values.
3 */
4trait ActionBuilder {
5
6 /**
7 * Constructs an `Action`.
8 *
9 * For example:
10 * {{{
11 * val echo = Action(parse.anyContent) { request =>
12 * Ok("Got request [" + request + "]")
13 * }
14 * }}}
15 *
16 * @tparam A the type of the request body
17 * @param bodyParser the `BodyParser` to use to parse the request body
18 * @param block the action code
19 * @return an action
20 */
21 def apply[A](bodyParser: BodyParser[A])(block: Request[A] => Result): Action[A] = new Action[A] {
22 def parser = bodyParser
23 def apply(ctx: Request[A]) = block(ctx)
24 }
25
26 /**
27 * Constructs an `Action` with default content.
28 *
29 * For example:
30 * {{{
31 * val echo = Action { request =>
32 * Ok("Got request [" + request + "]")
33 * }
34 * }}}
35 *
36 * @param block the action code
37 * @return an action
38 */
39 def apply(block: Request[AnyContent] => Result): Action[AnyContent] = apply(BodyParsers.parse.anyContent)(block)
40
41 /**
42 * Constructs an `Action` with default content, and no request parameter.
43 *
44 * For example:
45 * {{{
46 * val hello = Action {
47 * Ok("Hello!")
48 * }
49 * }}}
50 *
51 * @param block the action code
52 * @return an action
53 */
54 def apply(block: => Result): Action[AnyContent] = apply(_ => block)
55
56}从这些源文件知道 Action 里是个闭包就行,返回是个 Result 类型。至于执行时 request 值是怎么产生的还需研究下。
简单的 Result
目前我们只讲述简单的 Result: 一个具有状态代码的 HTTP Result, 一系列 HTTP 头和要发送到 Web 客户端的响应体.
这些 Result 由
play.api.mvc.SimpleResult 定义:1def index = Action {
2 SimpleResult(
3 header = ResponseHeader(200, Map(CONTENT_TYPE -> "text/plain")),
4 body = Enumerator("Hello world!")
5 )
6}当然,也有数个帮助方法让你创建通用的 Result,像下面例子中的
Ok Result:1def index = Action {
2 Ok("Hello world!")
3}这会产生与之上例中完全相同的 Result.
下面是几个创建种种 Result 的例子:
1val ok = Ok("Hello world!")
2val notFound = NotFound
3val pageNotFound = NotFound(<h1>Page not found</h1>)
4val badRequest = BadRequest(views.html.form(formWithErrors))
5val oops = InternalServerError("Oops")
6val anyStatus = Status(488)("Strange response type")所有的这些帮助方法可在
play.api.mvc.Results 特质和伴生对象中找到.重定向也是简单的 Result
重定向浏览器到一个新的 URL 是另一类简单的 Result. 然而, 这类 Result 类型不会带上响应体.
下面是些创建重定向 Result 的几个帮助方法:
1def index = Action {
2 Redirect("/user/home")
3}默认是利用
303 SEE_OTHER 响应类型, 但是 你可以根据需要设置特别的状态码:1def index = Action {
2 Redirect("/user/home", status = MOVED_PERMANENTLY)
3}Unmi 注: 返回 Result 类型的各方法定义在 Controller 所继承的 Results(.scala) 文件中,如 Ok,Redirect 等方法。
“TODO” 虚页面
你可以用一个定义为
TODO 的空的 Action 实现: 这个 Result 是一个标准的 ‘Not implemented yet’ 结果页:1def index(name:String) = TODOUnmi 注: TODO 定义在 trait Controller(.scala) 中:
1 val TODO = Action {
2 NotImplemented[play.api.templates.Html](views.html.defaultpages.todo())
3 }[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。