Json到Scala类型 - 任何列表

时间:2013-09-15 03:57:33

标签: arrays json parsing scala playframework-2.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]]和其他可能性。

提前致谢

1 个答案:

答案 0 :(得分: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 方法的参数。