01.行為, 控制器與結果

Actions, Controllers and Results,  https://github.com/playframework/Play20/wiki/ScalaActions  

行為(Action)是什麼?


Action 在此可被譯為 行為 或 動作. Play 應用程序在大多數的請求接收後, 由Action進行處理.

 play.api.mvc.Action 基本上是一個(play.api.mvc.Request => play.api.mvc.Result 函數, 處理一個請求並且產出一個要發送給客戶端的結果.

val echo = Action { request =>
  Ok("Got request [" + request + "]")
}
一個動作返回一個 play.api.mvc.Action值,代表 HTTP 回應發送到 Web 客戶端。在這個例子中的 Ok 構建了一個 200 OK 回應, 回應體包含一個 text/plain.

建立一個 Action

play.api.mvc.Action 伴生物件(companion object)提供了幾個輔助方法,供其建構一個 Action 的值。

首先最簡單的一個只需帶參數的表達式區塊,將欲返回的結果(Result)作為參數:
Action {
  Ok("Hello world")
}
這是最簡單的創建一個Action方式,但在這裡,我們沒有得到任何傳入的請求參考。但它往往是真正有用於 HTTP 請求來呼叫該 Action。

所以另外提供一個函數作為參數的 Action 建構器(builder) Request => Result:
Action { request =>
  Ok("Got request [" + request + "]")
}  

It is often useful to mark the request parameter as implicit so it can be implicitely used by other APIs that need it:

Action { implicit request =>
  Ok("Got request [" + request + "]")
}

創建一個 Action 值的最後一個方法是, 指定附加 BodyParser 參數:

Action(parse.json) { implicit request =>
  Ok("Got request [" + request + "]")

Body 解析器將包括在本手冊後面相關章節說明。現在你只需要知道,創建 Action 值的其他方法, 是使用一個預設的 Any content body 分析器。

Controllers are action generators

Controller is nothing more than a singleton object that generates Action values.

The simplest use case for defining an action generator is a method with no parameters that returns an Action value :

package controllers

import play.api.mvc._

object Application extends Controller {

  def index = Action {
    Ok("It works!")
  }
    
}

Of course, the action generator method can have parameters, and these parameters can be captured by the Action closure:

def hello(name: String) = Action {
  Ok("Hello " + name)
}

Simple results

For now we are just interested by simple results: An HTTP result with a status code, a set of HTTP headers and a body to be sent to the web client.

These results are defined by play.api.mvc.SimpleResult:

def index = Action {
  SimpleResult(
    header = ResponseHeader(200, Map(CONTENT_TYPE -> "text/plain")), 
    body = Enumerator("Hello world!")
  )
}

Of course there are several helpers available to create common results such as the Ok result we just used in the previous section:

def index = Action {
  Ok("Hello world!")
}

That is exactly the same as before.

Here are several examples to create various results:

val ok = Ok("Hello world!")
val notFound = NotFound
val pageNotFound = NotFound(<h1>Page not found</h1>)
val badRequest = BadRequest(views.html.form(formWithErrors))
val oops = InternalServerError("Oops")
val anyStatus = Status(488)("Strange response type")

All of these helpers can be found in the play.api.mvc.Results trait and companion object.

Redirects are simple results too

Redirecting the browser to a new URL is just another kind of simple result. However these result types don't take a response body.

There are several helpers available to create redirect results:

def index = Action {
  Redirect("/user/home")
}

The default is to use a 303 SEE_OTHER response type, but you can also specify a more specific status code if you need:

def index = Action {
  Redirect("/user/home", status = MOVED_PERMANENTLY)
}

Next: HTTP Routing




Comments