无法使用spray-json反序列化通用集合

时间:2015-12-10 14:16:24

标签: scala spray spray-json

我试图将json字符串反序列化为泛型集合。

我的代码看起来像这样:

class MyClass(json: String) {
  def collectionType1: Set[Type1] = loadElements[Type1]

  def collectionType2: Set[Type2] = ???

  private def loadElements[T]: Set[T] = {
    json.parseJson.convertTo[Set[T]]
  }
}

我也有以下定义(我对' Type2'有完全相同的定义,案例类看起来不同):

case class Type1(p1: String, p2: String)

object Type1JsonProtocol extends DefaultJsonProtocol {
  private implicit val collectionType1Format = jsonFormat2(Type1)

  implicit object Type1SetJsonReader extends JsonReader[Set[Type1]] {
    override def read(json: JsValue): Set[Type1] = json match {
      case JsArray(elements) => elements.map(_.convertTo[Type1]) toSet
      case x => deserializationError("Expected Collection as JsArray, but got " + x)
    }
  }
}

编译代码时,出现以下错误:

Error:(25, 29) Cannot find JsonReader or JsonFormat type class for Set[T]
    val res = json.convertTo[Set[T]]
                            ^

Error:(25, 29) not enough arguments for method convertTo: (implicit evidence$1: spray.json.JsonReader[Set[T]])Set[T].
Unspecified value parameter evidence$1.
    val res = json.convertTo[Set[T]]
                            ^
我显然错过了一些东西,但感觉它有点小。有没有人有任何线索?

谢谢!

1 个答案:

答案 0 :(得分:2)

以下是JsValue的convertTo函数的定义。

def convertTo[T](implicit evidence$1 : spray.json.JsonReader[T])

如您所见,您应该为类型T提供JsonReader作为impilicit参数。

你无法确定什么是真实类型的T及其JsonReader,所以只需再次使用隐式参数:

private def loadElements[T: JsonReader]: Set[T]

如果您不熟悉上述样式,可以像这样扩展代码:

private def loadElements[T](implicit p: JsonReader[T]): Set[T]

如果要调用此函数,则应提供具体类型而不是类型T及其JsonReader,如下所示:

def collectionType1: Set[Type1] = {
  import Type1JsonProtocol.*
  loadElements[Type1]
}

您可以通过此技术在编译时检测错误的de / serialization问题,而不是运行时。