§内容协商
内容协商是一种机制,它可以为同一个资源 (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/html
和 application/json
匹配。render
方法接受一个从 play.api.http.MediaRange
到 play.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() => ???
}
}
下一步:处理错误
在此文档中发现错误?此页面的源代码可以在 此处 找到。在阅读 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?前往 我们的社区论坛 与社区开始对话。