文档

§Actions、Controllers 和 Results

§什么是 Action?

Play 应用程序接收的大多数请求都由 Action 处理。

play.api.mvc.Action 本质上是一个 (play.api.mvc.Request => play.api.mvc.Result) 函数,它处理请求并生成要发送给客户端的结果。

def echo: Action[AnyContent] = Action { request => Ok("Got request [" + request + "]") }

一个 action 返回一个 play.api.mvc.Result 值,表示要发送给 Web 客户端的 HTTP 响应。在本例中,Ok 构造一个包含 text/plain 响应体的 200 OK 响应。

§构建 Action

在任何扩展 BaseController 的控制器中,Action 值都是默认的 action 构建器。此 action 构建器包含用于创建 Action 的多个帮助程序。

最简单的第一个方法只是将一个返回 Result 的表达式块作为参数。

Action {
  Ok("Hello world")
}

这是创建 Action 的最简单方法,但我们无法获取对传入请求的引用。访问调用此 Action 的 HTTP 请求通常很有用。

因此,还有另一个 action 构建器,它将一个 Request => Result 函数作为参数。

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

request 参数标记为 implicit 通常很有用,这样它就可以被需要它的其他 API 隐式使用。

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

如果您将代码分解为多个方法,那么您可以从 action 中传递隐式请求。

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
}

创建 Action 值的最后一种方法是指定一个额外的 BodyParser 参数。

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

Body 解析器将在本手册的后面部分介绍。现在您只需要知道创建 Action 值的其他方法使用默认的 任何内容体解析器

§Controllers 是 action 生成器

Play 中的控制器不过是一个生成 Action 值的对象。控制器通常定义为类,以利用 依赖注入

注意:请记住,在 Play 的未来版本中,将控制器定义为对象将不受支持。使用类是推荐的方法。

定义 action 生成器的最简单用例是一个没有参数的方法,它返回一个 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 头部和要发送到 Web 客户端的正文。

这些结果由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 路由


发现此文档中的错误?此页面的源代码可以在这里找到。在阅读文档指南后,请随时贡献拉取请求。有疑问或建议要分享?前往我们的社区论坛与社区进行交流。