§動作、控制器和結果
§什麼是動作?
Play 應用程式收到的請求大多數是由 Action
處理。
play.api.mvc.Action
基本上是一個 (play.api.mvc.Request => play.api.mvc.Result)
函式,用於處理請求並產生要傳送給客戶端的結果。
def echo: Action[AnyContent] = Action { request => Ok("Got request [" + request + "]") }
動作會傳回一個 play.api.mvc.Result
值,代表要傳送給網路用戶端的 HTTP 回應。在此範例中,Ok
會建構一個包含 text/plain 回應主體的 200 OK 回應。
§建立動作
在任何延伸 BaseController
的控制器中,Action
值是預設動作建構器。此動作建構器包含多個用於建立 Action
的輔助程式。
第一個最簡單的只將傳回 Result
的表示式區塊當作引數。
Action {
Ok("Hello world")
}
這是建立動作最簡單的方式,但我們無法取得對應的要求參考。通常存取呼叫此動作的 HTTP 要求會很有用。
因此,還有另一個動作建構器,它將函式 Request => Result
當作引數。
Action { request => Ok("Got request [" + request + "]") }
通常將 request
參數標示為 implicit
會很有用,這樣其他需要它的 API 就能隱含地使用它。
Action { implicit request => Ok("Got request [" + request + "]") }
如果已將程式碼區分成方法,就能從動作傳遞隱含的要求。
def action: Action[AnyContent] = Action { implicit request =>
anotherMethod("Some para value")
Ok("Got request [" + request + "]")
}
def anotherMethod(p: String)(implicit request: Request[_]) = {
// do something that needs access to the request
}
建立動作值的最後一種方式是指定額外的 BodyParser
引數。
Action(parse.json) { implicit request => Ok("Got request [" + request + "]") }
本文稍後將介紹主體剖析器。目前你只需要知道建立動作值的另一種方法會使用預設的 任何內容主體剖析器。
§控制器是動作產生器
Play 中的控制器只不過是一個產生 Action
值的物件。控制器通常定義為類別,以利用 相依性注入。
注意:請記住,在 Play 的未來版本中,將不支援將控制器定義為物件。建議使用類別。
定義動作產生器的最簡單使用案例是沒有參數並傳回 Action
值的方法。
package controllers
import javax.inject.Inject
import play.api.mvc._
class Application @Inject() (cc: ControllerComponents) extends AbstractController(cc) {
def index = Action {
Ok("It works!")
}
}
當然,動作產生器方法可以有參數,而且這些參數可以由 Action
閉包擷取。
def hello(name: String) = Action {
Ok("Hello " + name)
}
§簡單結果
目前我們只對簡單的結果感興趣:具有狀態碼、一組 HTTP 標頭和要傳送給網路客戶端主體的 HTTP 結果。
這些結果由 play.api.mvc.Result
定義
import play.api.http.HttpEntity
def index = Action {
Result(
header = ResponseHeader(200, Map.empty),
body = HttpEntity.Strict(ByteString("Hello world!"), Some("text/plain"))
)
}
當然,有幾個可用的輔助程式可以建立常見的結果,例如上面範例中的 Ok
結果
def index = Action {
Ok("Hello world!")
}
這會產生與之前完全相同的結果。
以下是建立各種結果的幾個範例
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")
所有這些輔助程式都可以在 play.api.mvc.Results
特質和伴隨物件中找到。
§重新導向也是簡單結果
將瀏覽器重新導向到新的 URL 只是另一種簡單的結果。但是,這些結果類型不採用回應主體。
有幾個可用的輔助程式可以建立重新導向結果
def index = Action {
Redirect("/user/home")
}
預設使用 303 SEE_OTHER
回應類型,但您也可以設定更具體的狀態碼(如果您需要的話)
def index = Action {
Redirect("/user/home", MOVED_PERMANENTLY)
}
§TODO
虛擬頁面
您可以使用定義為 TODO
的空 Action
實作:結果是標準的「尚未實作」結果頁面
def index(name: String) = TODO
下一步:HTTP 路由
在這個文件中發現錯誤?此頁面的原始程式碼可以在 這裡 找到。在閱讀 文件指南 後,請隨時提交拉取請求。有問題或建議要分享嗎?請前往 我們的社群論壇 與社群展開對話。