1

json オブジェクト Test があるとします。2 つの形式があります。

{
    "name": "Test",
    "id": "41"
}

{
    "object": {
        "name": "Test",
        "id": "41"
    }
}

Test.scala を作成しました:

case class Test (name: String, id: String)

object Test {

    implicit object FopReads extends Format[Test] {

        def reads(json: JsValue): Test = {
            Test (
                (json \ "name").as[String],
                (json \ "id").as[String]
            )
        }

        def writes(ts: Test) = JsObject(Seq(
            "name" -> JsString(ts.name),
            "id" -> JsString(ts.id)
        ))

    }
}

ご覧のとおり、実際には、最初の形式のみを扱います。Format[Test]私の質問は次のとおりです。両方の形式で読み書きできるように簡単に実装するにはどうすればよいですか? Play 2.10 で json メカニズムが変更されたことは知っています。このバージョンを変更して、やりたいことを行う必要がありますか?

お時間をいただきありがとうございます!

4

1 に答える 1

1

私の謙虚な意見では、あなたのアプローチは理想的ではなく、デザインを再考する必要があります. 理由を説明しましょう。

Format[A]両方のフォーマットを読み取ることができる を効果的に開発することはできますがFormat[A]、2 つのフォーマットを書き込むことができる を作成することはできません。

trait Format[T]{
    def reads (json: JsValue): T
    def writes (o: T): JsValue
}

ご覧のとおり、writes メソッドには単一のパラメーターがあるため、Format[Test]どちらの出力形式を使用する必要があるかを知ることはできません。理由に従えば、フォーマットを選択するのではなく、特定のJson フォーマットFormatからの/への書き込みと読み取りをトレイトに委譲することに同意するでしょう。適切な形式を選択するロジックは、適切な形式の読み取りと書き込みとは何の関係もないため、分離する必要があります。

そうは言っても、次の方法で Format[Test] を再利用できます。

case class ObjectParser(nestedFormatter:Format[T]) extends Format[T]{
    def reads (json: JsValue): T = nestedFormatter.read(json \ "object")
    def writes (o: T): JsValue  = JsObject("object" -> nestedFormatter.write(o))
}

このクラスは、既存のフォーマッタを取り、追加の「オブジェクト」ノード内で読み書きできるようにします。

URL エンドポイントに従って 2 つの異なる回答を生成または解析する必要があるコントローラーがあるとします。

object TestController extends Controller {

    def endPoint1Action = Action{
        implicit request => 
        generateResponse(FopReads)
    }

    def endPoin21Action = Action{
        implicit request => 
        generateResponse(ObjectParser(FopReads))
    }

    def generateResponse(formatter:Format[Test])(implicit request:Request[AnyContent]):Response  = BadRequest("!")

}
于 2013-01-18T14:15:40.403 に答える