10

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(...)
  }
}

これには Play のイディオムがありますか? それとも、リクエストから Accept ヘッダーの値を取得するだけですか?

4

2 に答える 2

14

Play 2.1 では、次のように記述できます。

request match {
  case Accepts.Xml() => Ok(<error>{e.message}</error>)
  case Accepts.Json() => Ok(…)
}

case ステートメントは記述されている順序で試行されるため、クライアントが HTTPAcceptヘッダーを*/*最初のヘッダーに設定すると、一致します (この例ではcase Accepts.Xml())。したがって、Accepts.Html()ブラウザはAcceptヘッダーを に設定するため、通常はケースを最初に記述し*/*ます。

(注: Javaでの同様の質問に対するこの回答にも興味があるかもしれません)

于 2012-06-16T09:32:32.813 に答える
1

Play をリリースしました。mimerender と呼ばれるコンテンツ ネゴシエーション用の 2.0 モジュール ( 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 でのみテストされていることに注意してください。

于 2012-12-12T22:06:05.463 に答える