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