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

标签 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]]
                            ^

我显然遗漏了一些东西,但感觉它很小。有人知道吗?

谢谢!

最佳答案

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

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

如您所见,您应该为 Type T 提供 JsonReader 作为隐式参数。

你无法决定什么是真实类型的 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]
}

通过这种技术,您可以在编译时而不是运行时检测到错误的反序列化问题。

关于scala - 无法使用 spray-json 反序列化通用集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34204153/

相关文章:

java - java 类的隐式 jsonFormat

scala - 用Spray-json处理默认值的好方法是什么

json - 如何将所有拒绝内容转换为Spray中的自定义json?

scala - 如何正确处理 Future.sequence 中的个别异常?

string - Scala 如何转义 3 个双引号

scala - Spark DataFrame - 从列中删除空值

akka - 使用 Akka HTTP(正式名称为 Spray)的 GET 请求的查询参数

scala - 在这个Future和Thread.sleep示例中如何使用spray.io实现高并发?

java - 如何将 Java 中的 SortedSet 转换为 Scala 中的 Seq

scala - 使用Spray json序列化Map [String,Any]