0

我从我无法控制的上游服务器接收 JSON 响应以进行修改。

JSON 可以具有以下格式

{"data":[["Some_text","boolean",["key_string1","key_string2"]]]}

或者它也可以显示为

{"data":[["Some_text","boolean","key_string2"]]}

或者它可以显示为两者的组合。

{"data":[["Some_text","boolean",["key_string1","key_string2"]],["Some_text","boolean","key_string2"]]}

如果它们不混合,我可以单独为每种格式定义 READS。但是,鉴于数据可能是混合格式,我无法理解应该如何编写读取,以便在转换之前检查底层类型是字符串还是数组?

是否可以说类似

  (
    (JsPath)(0).read[String] and
    (JsPath)(1).read[Boolean] and
    (JsPath)(2).read( **if type is simple, String OR if type is array, then seq** )
  )(SomeGloriousCaseClass)

我该如何解决这个反序列化问题?

4

1 回答 1

1

为了好玩,我实施了一个解决方案。您可能需要稍微调整一下:

private def toSeq(jsValue: JsValue): JsResult[Seq[String]] = {
    jsValue match {
      case JsArray(es:Seq[JsValue]) ⇒ sequence(es.map(e ⇒ toSeq(jsValue))).map(_.flatten)
      case JsString(s) ⇒ JsSuccess(s :: Nil)
      case _ ⇒ JsError("INVALID")
    }
  }

  private def sequence[A](seq:Seq[JsResult[A]]):JsResult[Seq[A]] = {
    seq.foldLeft(JsResult.applicativeJsResult.pure(Seq[A]()))((acc, next) ⇒ for(acc2 ← acc; next2 ← next) yield acc2 :+ next2)
  }

希望它有所帮助,如果需要,我们很乐意提供进一步的解释。

于 2016-12-01T13:19:01.160 回答