Scala 具有列表的泛型类型的JsonReader

Scala 具有列表的泛型类型的JsonReader,scala,spray-json,Scala,Spray Json,我有以下域模型和JsonFormat/JsonReader定义: import spray.json._ case class User(name: String) case class ValueResponse[T](value: T) case class ValueListResponse[T](values: List[T]) object ApiProtocol extends DefaultJsonProtocol { // some of my entities ha

我有以下域模型和JsonFormat/JsonReader定义:

import spray.json._

case class User(name: String)

case class ValueResponse[T](value: T)
case class ValueListResponse[T](values: List[T])

object ApiProtocol extends DefaultJsonProtocol {

  // some of my entities have JsonFormat but some only JsonReader
  implicit val userFormat = jsonFormat1[String, User](User)

  implicit def valueReader[T : JsonReader] = new JsonReader[ValueResponse[T]] {
    def read(value: JsValue): ValueResponse[T] = {
      value.asJsObject.fields.get("value") match {
        case Some(value: JsObject) => ValueResponse(value.convertTo[T])
      }
    }
  }

  implicit def valueListReader[T : JsonReader] = new JsonReader[ValueListResponse[T]] {
    def read(value: JsValue): ValueListResponse[T] = {
      value.asJsObject.fields.get("values") match {
        case Some(values: JsArray) => ValueListResponse(values.convertTo[List[T]])
                                                                        ^
[error] Cannot find JsonReader or JsonFormat type class for List[T]
      }
    }
  }
}
我有两个隐式JsonReader定义:

import spray.json._

case class User(name: String)

case class ValueResponse[T](value: T)
case class ValueListResponse[T](values: List[T])

object ApiProtocol extends DefaultJsonProtocol {

  // some of my entities have JsonFormat but some only JsonReader
  implicit val userFormat = jsonFormat1[String, User](User)

  implicit def valueReader[T : JsonReader] = new JsonReader[ValueResponse[T]] {
    def read(value: JsValue): ValueResponse[T] = {
      value.asJsObject.fields.get("value") match {
        case Some(value: JsObject) => ValueResponse(value.convertTo[T])
      }
    }
  }

  implicit def valueListReader[T : JsonReader] = new JsonReader[ValueListResponse[T]] {
    def read(value: JsValue): ValueListResponse[T] = {
      value.asJsObject.fields.get("values") match {
        case Some(values: JsArray) => ValueListResponse(values.convertTo[List[T]])
                                                                        ^
[error] Cannot find JsonReader or JsonFormat type class for List[T]
      }
    }
  }
}
  • valueReader[T]
    用于
    ValueResponse[T]
    (用于类型为T的单个值)
  • valueListReader[T]
    用于
    ValueListResponse[T]
    (用于带有T类型值列表的响应)
两种类型的读卡器定义几乎相同。 第一个定义可以正常工作,但第二个编译器失败并出现错误

找不到列表[T]的JsonReader或JsonFormat类型类。

有趣的是,如果我用
T:JsonFormat
替换参数约束
T:JsonReader
,它编译得很好

但是我想保留
T:JsonReader
约束,而不是
T:JsonFormat
,因为我的一些实体(
T
)将只有reader实现


我怀疑我弄乱了参数定义的界限,但我不明白是怎么回事。

我怀疑spray可能只对
JsonFormat[List[t]]
给定了
JsonFormat[t]
,而不是
JsonReader[List[t]
给定了
JsonReader[t]
。幸运的是,这很容易做到,比如:

implicit def listReader[T : JsonReader]: JsonReader[List[T]] = new JsonReader[List[T]] {
  def read(value: JsValue): List[T] = value match {
    case JsArray(elements) => elements.map(_.convertTo[T]).toList
    case x => deserializationError("Expected List as JsArray, but got " + x)
  }
}

实际上,这让我想知道为什么他们不单独定义所有的隐式
JsonReader
s和
JsonWriter
s,然后使用一个
implicit def bothToFormat[t:JsonReader:JsonWriter]:JsonFormat[t]

,我怀疑spray可能只有
JsonFormat[List[t]的隐式定义
给定一个
JsonFormat[T]
,而不是
JsonReader[List[T]
给定一个
JsonReader[T]
。幸运的是,这很容易做到,比如:

implicit def listReader[T : JsonReader]: JsonReader[List[T]] = new JsonReader[List[T]] {
  def read(value: JsValue): List[T] = value match {
    case JsArray(elements) => elements.map(_.convertTo[T]).toList
    case x => deserializationError("Expected List as JsArray, but got " + x)
  }
}

这实际上让我想知道为什么他们不单独定义所有的隐式
JsonReader
s和
JsonWriter
s,然后使用一个
implicit def bothToFormat[t:JsonReader:JsonWriter]:JsonFormat[t]

谢谢你的回答,似乎是这样的。谢谢你的回答,似乎是这样。您是否尝试过添加
导入默认JSONProtocol.\u
?是否尝试过添加
导入默认JSONProtocol.\u