简体   繁体   English

Playframework 2.0.X Scala-如何为一个对象实现多个json读/写?

[英]Playframework 2.0.X scala - How to implement multiple json reads/writes for an object?

Let's assume that have a json object Test. 假设有一个JSON对象Test。 It has two formats : 它有两种格式:

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

and

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

I created Test.scala : 我创建了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)
        ))

    }
}

As you can see, actually, I only deal with the first format. 如您所见,实际上,我只处理第一种格式。 My question is : How do I easily implement a Format[Test] that it can read and write in both formats ? 我的问题是:如何轻松实现可以以两种格式读写的Format[Test] I know that the json mechanism have changed in play 2.10. 我知道json机制在play 2.10中已更改。 Should I change for this version to do what I want ? 我应该更改此版本以执行我想要的吗?

Thank you for your time ! 感谢您的时间 !

In my humble opinion, your approach is not ideal and you have to rethink about your design. 以我的拙见,您的方法并不理想,您必须重新考虑您的设计。 Let me explain you why. 让我解释一下原因。

While you could effectively develop a Format[A] which is able to read both formats, you are not able to write a Format[A] which can write the two formats 虽然你可以有效地开发一个Format[A]这是能够读取这两种格式,你不能写Format[A]可以写出两种格式

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

As you see, the writes method has a single parameter, so your Format[Test] won't be able to know if it should use one or the other output format. 如您所见,writes方法只有一个参数,因此您的Format[Test]将无法知道它是否应使用一种或另一种输出格式。 If you followed the reasoning you would agree that the Format trait is delegated to write and read from/to a specific Json Format, not to choose between formats. 如果遵循该推理,则您将同意将Format特征授权给特定的 Json Format读写,而不是在两种格式之间进行选择。 Your logic to choose the right format has nothing to do with reading and writing the right format, and you should decouple it. 选择正确格式的逻辑与读取和写入正确格式无关,您应该将其解耦。

Saying that, you can re-use your Format[Test] in the following way: 这样一来,您可以通过以下方式重新使用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))
}

This class would take any existing formatter and make it able to read and write inside an additional "object" node. 该类将使用任何现有的格式化程序,并使其能够在其他“对象”节点内进行读取和写入。

Imagine now you have a controller which needs to generate or parse two different answers according to the url endpoints: 想象一下,现在您有一个控制器,它需要根据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("!")

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM