spray-json 找不到类型为 List[T] 的 JsonReader
spray-json can't find JsonReader for type List[T]
我正在为案例 classes 创建自定义 json 阅读器,但找不到用于其他案例的 List[T] 的隐式 JsonReader 类型 class class.
当我检查 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: spray.json.JsonReader[List[com.xx.Test]])List[com.xx.Test].
Unspecified value parameter evidence.
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)
^
我了解到限制来自spray-json:
spray-json 's type class infrastructure is build around the (Root)JsonFormat type, not the (Root)JsonReader. So you'll indeed have to provide a "Format" even if you are just reading.
克服问题;我创建了另一个特征 extends RootJsonFormat 而不是 reader 并用基本上未实现的方法覆盖 write 方法。
trait EmptyWriterFormat[T] extends RootJsonFormat[T] {
override def write(o: T): JsValue = ???
}
我认为问题与 DefaultJsonProtocol
中 List[T]
的 JsonReader
是 RootJsonFormat
(不是 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")
}
如果您知道一个只涉及读者的干净解决方案,请告诉我,因为我自己 运行 解决了这个问题,但找不到其他任何东西。
我正在为案例 classes 创建自定义 json 阅读器,但找不到用于其他案例的 List[T] 的隐式 JsonReader 类型 class class.
当我检查 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: spray.json.JsonReader[List[com.xx.Test]])List[com.xx.Test].
Unspecified value parameter evidence.
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)
^
我了解到限制来自spray-json:
spray-json 's type class infrastructure is build around the (Root)JsonFormat type, not the (Root)JsonReader. So you'll indeed have to provide a "Format" even if you are just reading.
克服问题;我创建了另一个特征 extends RootJsonFormat 而不是 reader 并用基本上未实现的方法覆盖 write 方法。
trait EmptyWriterFormat[T] extends RootJsonFormat[T] {
override def write(o: T): JsValue = ???
}
我认为问题与 DefaultJsonProtocol
中 List[T]
的 JsonReader
是 RootJsonFormat
(不是 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")
}
如果您知道一个只涉及读者的干净解决方案,请告诉我,因为我自己 运行 解决了这个问题,但找不到其他任何东西。