簡體   English   中英

如何在Play Framework 2.x中實現嵌入對象的隱式Json Writes

[英]How to implement implicit Json Writes of embedded object in Play Framework 2.x

FooBar有兩個類。 Foo包含一個Bar字段。 問題是,如何為類Foo實現隱式json Writes

這是代碼:

package models

import play.api.libs.json._

case class Foo(id: String, bar: Bar)

object Foo {
  implicit val implicitFooWrites = new Writes[Foo] {
    def writes(foo: Foo): JsValue = {
      Json.obj(
        "id" -> foo.id,
        "bar" -> foo.bar
      )
    }
  }
}

case class Bar(x: String, y: Int)

object Bar {
  implicit val implicitBarWrites = new Writes[Bar] {
    def writes(bar: Bar): JsValue = {
      Json.obj(
        "x" -> bar.x,
        "y" -> bar.y
      )
    }
  }
}

當我嘗試編譯時,我收到以下錯誤:

沒有找到類型模型的Json反序列化器.Bar。 嘗試為此類型實現隱式寫入或格式。

我不明白這個編譯器錯誤,因為我為models.Bar類實現了一個隱式Writes。 這里有什么問題?

這是一個可見性的問題,當聲明隱式Writes [Foo]時,你沒有看到它的隱式Writes [Bar]:

scala> :paste
// Entering paste mode (ctrl-D to finish)

import play.api.libs.json._

case class Bar(x: String, y: Int)

object Bar {
  implicit val implicitBarWrites = new Writes[Bar] {
    def writes(bar: Bar): JsValue = {
      Json.obj(
        "x" -> bar.x,
        "y" -> bar.y
      )
    }
  }
}

case class Foo(id: String, bar: Bar)

object Foo {

  import Bar._

  implicit val implicitFooWrites = new Writes[Foo] {
    def writes(foo: Foo): JsValue = {
      Json.obj(
        "id" -> foo.id,
        "bar" -> foo.bar
      ) 
    } 
  }     
}

// Exiting paste mode, now interpreting.

import play.api.libs.json._
defined class Bar
defined module Bar
defined class Foo
defined module Foo

scala> Json.prettyPrint(Json.toJson(Foo("23", Bar("x", 1))))
res0: String = 
{
  "id" : "23",
  "bar" : {
    "x" : "x",
    "y" : 1
  }
}

此外,如果您使用的是Play 2.1+,請務必查看2.10宏的全新用法: http//www.playframework.com/documentation/2.1.0/ScalaJsonInception

如果您對使用case類和val / vars的名稱作為json輸出中的鍵使用感到滿意,就像你的BTW一樣,那么你可以使用兩個單行:

implicit val barFormat = Json.writes[Bar]
implicit val fooFormat = Json.writes[Foo]

這將給你完全相同的:

scala> import play.api.libs.json._
import play.api.libs.json._

scala> case class Bar(x: String, y: Int)
defined class Bar

scala> case class Foo(id: String, bar: Bar)
defined class Foo

scala> implicit val barWrites = Json.writes[Bar]
barWrites: play.api.libs.json.OWrites[Bar] = play.api.libs.json.OWrites$$anon$2@257cae95

scala> implicit val fooWrites = Json.writes[Foo]
fooWrites: play.api.libs.json.OWrites[Foo] = play.api.libs.json.OWrites$$anon$2@48f97e2a

scala> Json.prettyPrint(Json.toJson(Foo("23", Bar("x", 1))))
res0: String = 
{
  "id" : "23",
  "bar" : {
    "x" : "x",
    "y" : 1
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM