文档

§内容协商

内容协商是一种机制,它可以为同一个资源 (URI) 提供不同的表示形式。它对于编写支持多种输出格式(XML、JSON 等)的 Web 服务很有用。服务器驱动的协商本质上是使用 Accept* 请求头完成的。您可以在 HTTP 规范 中找到有关内容协商的更多信息。

§语言

您可以使用 play.api.mvc.RequestHeader#acceptLanguages 方法获取请求的可接受语言列表,该方法从 Accept-Language 头部获取这些语言并根据其质量值对它们进行排序。Play 在 play.api.mvc.Controller#lang 方法中使用它,该方法为您的操作提供一个隐式的 play.api.i18n.Lang 值,因此它们会自动使用最佳语言(如果您的应用程序支持,否则将使用您的应用程序的默认语言)。

§内容

类似地,play.api.mvc.RequestHeader#acceptedTypes 方法提供了请求可接受的结果 MIME 类型列表。它从 Accept 请求头中获取它们,并根据它们的质量因子对它们进行排序。

实际上,Accept 标头并不真正包含 MIME 类型,而是媒体范围(*例如*,接受所有文本结果的请求可以设置 text/* 范围,而 */* 范围表示所有结果类型都是可接受的)。控制器提供了一个更高级的 render 方法来帮助您处理媒体范围。例如,考虑以下操作定义

val list: Action[AnyContent] = Action { implicit request =>
  val items = Item.findAll
  render {
    case Accepts.Html() => Ok(views.html.list(items))
    case Accepts.Json() => Ok(Json.toJson(items))
  }
}

Accepts.Html()Accepts.Json() 是提取器,用于测试给定的媒体范围是否分别与 text/htmlapplication/json 匹配。render 方法接受一个从 play.api.http.MediaRangeplay.api.mvc.Result 的偏函数,并尝试将其应用于请求 Accept 标头中找到的每个媒体范围,按优先级排序。如果您的函数不支持任何可接受的媒体范围,则将返回 NotAcceptable 结果。

例如,如果客户端使用以下 Accept 标头值发出请求:*/*;q=0.5,application/json,这意味着它接受任何结果类型,但更喜欢 JSON,则上述代码将返回 JSON 表示。如果另一个客户端使用以下 Accept 标头值发出请求:application/xml,这意味着它只接受 XML,则上述代码将返回 NotAcceptable

§请求提取器

请参阅 play.api.mvc.AcceptExtractors.Accepts 对象的 API 文档,了解 Play 在 render 方法中开箱即用的 MIME 类型列表。您可以使用 play.api.mvc.Accepting 案例类轻松地为给定的 MIME 类型创建自己的提取器,例如以下代码创建了一个提取器,用于检查媒体范围是否与 audio/mp3 MIME 类型匹配

  val AcceptsMp3 = Accepting("audio/mp3")
  render {
    case AcceptsMp3() => ???
  }
}

下一步:处理错误


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