【问题标题】:Playframework 2.0.X scala - How to implement multiple json reads/writes for an object?Playframework 2.0.X scala - 如何为一个对象实现多个 json 读/写?
【发布时间】:2013-01-19 21:33:43
【问题描述】:

让我们假设有一个 json 对象 Test。 它有两种格式:

{
    "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] 以两种格式读写?我知道 json 机制在 play 2.10 中发生了变化。我应该改变这个版本来做我想做的事吗?

感谢您的宝贵时间!

【问题讨论】:

    标签: json scala playframework-2.0


    【解决方案1】:

    在我看来,您的方法并不理想,您必须重新考虑您的设计。让我解释一下原因。

    虽然您可以有效地开发能够读取两种格式的Format[A],但您无法编写可以写入两种格式的Format[A]

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

    如您所见,writes 方法只有一个参数,因此您的Format[Test] 将无法知道它是否应该使用一种或另一种输出格式。如果您遵循推理,您会同意 Format 特征被委派来写入和读取 特定 Json 格式,而不是在格式之间进行选择。您选择正确格式的逻辑与读写正确格式无关,您应该将其解耦。

    也就是说,您可以通过以下方式重新使用您的 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 端点生成或解析两个不同的答案:

    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("!")
    
    }
    

    【讨论】:

    • 这就是我的想法。谢谢,这有助于我清楚地提高对此的理解。
    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-26
    相关资源
    最近更新 更多