【问题标题】:Json to Scala type - list of list of anyJson 到 Scala 类型 - 任何列表的列表
【发布时间】:2013-09-19 11:13:06
【问题描述】:

我正在尝试解析一个包含数组数组的 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]] 和其他可能性。

提前致谢

【问题讨论】:

    标签: arrays json parsing scala playframework-2.1


    【解决方案1】:

    问题在于 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-11-20
    • 2021-02-25
    • 1970-01-01
    • 2018-07-26
    • 2017-10-02
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多