播放 JSON JsPath 条件类型
Play JSON JsPath Conditional Types
我收到来自我无法控制的上游服务器的 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。
但是,鉴于数据可能是混合格式,我无法思考应该如何编写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)
如何解决这个反序列化问题?
为了好玩,我实现了一个解决方案。您可能需要稍微调整一下:
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)
}
希望对您有所帮助,如果需要,我们很乐意提供进一步的解释。
我收到来自我无法控制的上游服务器的 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。 但是,鉴于数据可能是混合格式,我无法思考应该如何编写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)
如何解决这个反序列化问题?
为了好玩,我实现了一个解决方案。您可能需要稍微调整一下:
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)
}
希望对您有所帮助,如果需要,我们很乐意提供进一步的解释。