spray-json找不到类型为List [T]的JsonReader

时间:2016-05-25 03:56:18

标签: scala spray-json

我为案例类创建了自定义json阅读器,但它找不到List [T]的隐式JsonReader类型类,它在其他案例类中使用。

当我检查DefaultJsonProtocol时,它已经具有集合的隐式格式;

  implicit def listFormat[T :JsonFormat] = new RootJsonFormat[List[T]] {
    def write(list: List[T]) = JsArray(list.map(_.toJson).toVector)
    def read(value: JsValue): List[T] = value match {
      case JsArray(elements) => elements.map(_.convertTo[T])(collection.breakOut)
      case x => deserializationError("Expected List as JsArray, but got " + x)
    }
  }

这是简化的代码;

case class Test(i: Int, d: Double)
case class ListOfTest(t: List[Test])

trait TestResultFormat extends DefaultJsonProtocol {

  import CustomFormat._

    implicit object TestJsonFormat extends RootJsonReader[Test] {

    override def read(json: JsValue): Test = {

      val jsObject = json.asJsObject
      val jsFields = jsObject.fields

      val i = jsFields.get("i").map(_.convertTo[Int]).getOrElse(0)
      val d = jsFields.get("d").map(_.convertTo[Double]).getOrElse(0d)

      Test(i, d)
    }
  }

  implicit object ListOfTestJsonFormat extends RootJsonReader[ListOfTest] {

    override def read(json: JsValue): ListOfTest = {

      val jsObject = json.asJsObject
      val jsFields = jsObject.fields

      val tests = jsFields.get("hs").map(_.convertTo[List[Test]]).getOrElse(List.empty)

      ListOfTest(tests)
    }
  }

}

这是错误;

Error:(230, 53) not enough arguments for method convertTo: (implicit evidence$1: spray.json.JsonReader[List[com.xx.Test]])List[com.xx.Test].
Unspecified value parameter evidence$1.
      val tests = jsFields.get("hs").map(_.convertTo[List[Test]]).getOrElse(List.empty)
                                                    ^
Error:(230, 53) Cannot find JsonReader or JsonFormat type class for List[com.xx.Test]
      val tests = jsFields.get("hs").map(_.convertTo[List[Test]]).getOrElse(List.empty)
                                                ^

2 个答案:

答案 0 :(得分:4)

我认为问题与JsonReaderList[T] DefaultJsonProtocolRootJsonFormat(不是RootJsonReader)的事实有关,基本上意味着你可以读它并写它。因此,当您尝试阅读List[Item]时,预计您还可以撰写Item。因此,您可以使用RootJsonFormat代替并在您尝试编写时抛出异常(因为您不支持它)。例如:

import spray.json._

implicit object TestJsonFormat extends RootJsonFormat[Test] {

  override def read(json: JsValue): Test = {

    val jsObject = json.asJsObject
    val jsFields = jsObject.fields

    val i = jsFields.get("i").map(_.convertTo[Int]).getOrElse(0)
    val d = jsFields.get("d").map(_.convertTo[Double]).getOrElse(0d)

    Test(i, d)
  }

  override def write(obj: Test): JsValue = serializationError("not supported")
}

如果您知道仅涉及读者的干净解决方案,请告诉我,因为我自己遇到了这个问题而无法找到其他任何问题。

答案 1 :(得分:3)

我了解到限制来自spray-json:

  

spray-json的类型基础结构是围绕(Root)JsonFormat类型而不是(Root)JsonReader构建的。所以你确实必须提供一个"格式"即使你只是在阅读。

Check here.

克服问题;我创建了另一个特性扩展RootJsonFormat而不是reader并覆盖了write方法,基本上没有实现方法。

trait EmptyWriterFormat[T] extends RootJsonFormat[T] {
  override def write(o: T): JsValue = ???
}