在Rails中,我能够做类似以下的事情:
respond_to do |format|
format.xml { ... }
format.json { ... }
end
并根据客户端在Accept标头中提供的内容执行相应的块。
如何在Play 2.0(Scala)中执行相同的操作?
我希望做一些看起来像这样的事情:
try {
Resources.delete(id)
Ok("done")
}
catch {
case e: ClientReportableException =>
?? match {
case "application/xml" => Ok(<error>{e.message}</error>)
case "application/json" => Ok(...)
}
}
是否有播放习惯用法,或者我只是从请求中获取Accept标头的值?
答案 0 :(得分:14)
在Play 2.1中,您可以编写以下内容:
request match {
case Accepts.Xml() => Ok(<error>{e.message}</error>)
case Accepts.Json() => Ok(…)
}
case语句按编写顺序进行尝试,因此如果客户端将HTTP Accept
标头设置为*/*
,则第一个标头将匹配(在此示例中为case Accepts.Xml()
)。因此,您通常希望首先编写Accepts.Html()
案例,因为浏览器会将Accept
标题设置为*/*
。
(注意:对于Java中的类似问题,您可能也对this answer感兴趣)
答案 1 :(得分:1)
我刚刚发布了Play!用于内容协商的2.0模块,名为mimerender(http://github.com/martinblech/play-mimerender)。
这个想法是你必须定义从你的域类到不同表示的映射:
val m = mapping(
"text/html" -> { s: String => views.html.index(s) },
"application/xml" -> { s: String => <message>{s}</message> },
"application/json" -> { s: String => toJson(Map("message" -> toJson(s))) },
"text/plain" -> identity[String]_
)
完成一次后,您可以在所有控制器中重复使用该映射:
object Application extends Controller {
def index = Action { implicit request =>
m.status(200)("Hello, world!")
}
}
请注意,这是一个非常早期的版本,仅在Play 2.0.4上进行了测试