1

我正在尝试解析一个包含数组数组的 json 对象。示例 json 如下所示 -

val data = """
         {
           "ColumnTitles": ["Product Code","Product Name","Quantity"],
           "CellValues": [
             ["prod01","Half Shirt",2],
             ["prod02","Full Shirt",1],
             ["prod03","Jeans Pant",2]
           ]
         }
        """
val dataJson = Json.parse(data)
val cTitles = ((dataJson \ "ColumnTitles").asOpt[List[String]).get
val cValues = ((dataJson \ "CellValues").asOpt[List[List[Any]]]).get

我知道,最后一行会显示编译错误,但你明白我想要什么 -Any可以是 String、Int 或其他 json 对象。事实上,用户将发送一些任意的表数据,其列数、行数、列数据类型——一切在编译时都是未知的,应该根据运行时的数据来确定。我怎样才能达到预期的效果?我尝试过 Array[Array[Any]] 和其他可能性。

提前致谢

4

1 回答 1

3

问题在于Any的解组。该类型没有阅读器,而 Scala 需要一个编译时间。您不能将其推迟到运行时。这个问题有两种可能的解决方案:

  • 您可以选择另一种读者存在的类型,例如 JsValue。然后该行变为:

    val cValues = ((dataJson \ "CellValues").asOpt[List[List[JsValue]]]).get

  • 您可以为Any类型提供一个阅读器。您的示例代码的阅读器会这样:

    implicit val anyReads = new Reads[Any] {
      def reads(json: JsValue): JsResult[Any] = json match {
        case JsString(s) => JsSuccess(s)
        case JsNumber(n) => JsSuccess(n.toLong)
        case _ => JsError()
      }
    }
    
    val cValues = ((dataJson \ "CellValues").asOpt[List[List[Any]]]).get

    因为anyReads是隐式的,所以您不必将其指定为asOpt方法的参数。

于 2013-09-15T14:41:59.403 回答