播放Scala JSON写作&继承

时间:2016-08-29 06:58:07

标签: json scala inheritance playframework

// Item.scala

package model
trait Item {val id: String}

class MItem(override val id: String, val name: String) extends Item

class DItem(override val id: String, override val name: String, val name2: String)
  extends MItem(valid, name, name2)

object ItemWrites {

  implicit  val MItemWrites = new Writes[MItem] {
    def writes(dItem: MItem) = Json.obj(
      "id" -> mItem.id,
      "name" -> mItem.name
    )
  }

  implicit  val DItemWrites = new Writes[DItem] {
    def writes(dItem: DItem) = Json.obj(
      "id" -> dItem.id,
      "name" -> dItem.name,
      "name2" -> dItem.name2
    )
  }

}

// Response.scala

package model
import ItemWrites.MItemWrites
import ItemWRites.DItemWrites

trait Response {
  val title : String,
  val items : Seq[Item],
}

case class MResponse(title: String, items: Seq[MItem]) extends Response

case class DResponse(title: String, items: Seq[DItem]) extends Response

object ResponseWrites  {

  implicit val mResponseWrite = new Writes[MResponse] {

    def writes(mResponse: MResponse) = Json.obj(
      "title" -> mResponse.title,
      "items" -> mResponse.items
    )
  }

  implicit val dResponseWrite = new Writes[DResponse] {

    def writes(dResponse: DResponse) = Json.obj(
      "title" -> dResponse.title,
      "items" -> dResponse.items // **compile time error**
    )
  }

}

我在行dResponse.items上遇到编译时错误。

> [error]  Note: implicit value dtcTopicPageResponseWrite is not
> applicable here because it comes after the application point and it
> lacks an explicit result type
> [error] "items" -> dResponse.items

似乎这种情况正在发生,因为DItem继承了MItem的形式,并且编译在子类和超类之间变得混乱。我该如何解决这个问题。

3 个答案:

答案 0 :(得分:1)

通过明确说明ItemWrites中声明的object ItemWrites { implicit val MItemWrites:Writes[MItem] = new Writes[MItem] { def writes(mItem: MItem) = Json.obj( "id" -> mItem.id, "name" -> mItem.name ) } implicit val DItemWrites:Writes[DItem] = new Writes[DItem] { def writes(dItem: DItem) = Json.obj( "id" -> dItem.id, "name" -> dItem.name, "name2" -> dItem.name2 ) } } 类型,我能够在Scala 2.11,Play 2.5.x中编译代码,即:

NullPointerException

一旦我这样做了,Scala就能找出哪个隐含正确而且离开了。

答案 1 :(得分:1)

您应该明确设置将使用哪个Writer [T],因为它们使用继承。我没有测试下面的代码,但它应该编译并工作;

implicit val dResponseWrite = new Writes[DResponse] {

    import ItemWrites.DItemWrites

    def writes(dResponse: DResponse) = Json.obj(
      "title" -> dResponse.title,
      "items" -> Json.toJson(dResponse.items) // **compile time error**
    )
  }

答案 2 :(得分:0)

我认为你有一个超级类型项的写入更好,它只会匹配大小写以检查它的类型并执行toJson。不要忘记隐式导入

object ItemWrites {

  implicit  val MItemWrites = new Writes[MItem] {
    def writes(dItem: MItem) = Json.obj(
      "id" -> mItem.id,
      "name" -> mItem.name
    )
  }

  implicit  val DItemWrites = new Writes[DItem] {
    def writes(dItem: DItem) = Json.obj(
      "id" -> dItem.id,
      "name" -> dItem.name,
      "name2" -> dItem.name2
    )
  }

  implicit  val ItemWrites = new Writes[Item] {
    def writes(item: Item) = item match {
     case i: DItem => i.toJson //code for converting DItem to Json
     case i: MItem => i.toJson //code to convert MItem to Json
     case _ => throws new RuntimeException("Unsupported Type.")
   }
  }
}