Scala如何判断JSON字段类型并从字符串或数组结构中提取对应值
你原有代码存在两个核心错误:
field是JSON游标类型,不是field对应的JSON值本身,直接调用asInstanceOf[String]做类型判断永远不成立as[Seq[field[0]]]属于语法错误,泛型参数不能传入运行时变量,你需要先定义数组元素的结构,或者通过游标逐层取值
实现方案
目前Scala生态处理JSON最常用的两个库是Circe和Play JSON,核心逻辑一致:先尝试将节点解析为String,解析失败则尝试解析为数组,取第一个元素的value字段值,两个库的实现代码分别如下:
Circe版本
import io.circe._ import io.circe.generic.semiauto._ // 定义数组内元素的结构,也可以直接用游标逐层取值省略这个定义 case class FieldItem(count: Int, value: String) implicit val fieldItemDecoder: Decoder[FieldItem] = deriveDecoder[FieldItem] val fieldValue: String = field.as[String].fold( // 解析String失败,走数组分支 _ => field.as[Seq[FieldItem]] match { case Right(items) if items.nonEmpty => items.head.value // 数组为空或解析失败的兜底逻辑,可根据业务调整 case _ => "" }, // 解析String成功,直接取值 str => str ) rowFiltered.set("field", fieldValue)
如果不想定义样例类,可以用游标直接取值,写法更简洁:
val fieldValue: String = field.as[String].getOrElse( field.downArray.downField("value").as[String].getOrElse("") )
Play JSON版本
import play.api.libs.json._ case class FieldItem(count: Int, value: String) implicit val fieldItemFormat: OFormat[FieldItem] = Json.format[FieldItem] val fieldValue: String = field.validate[String].fold( _ => field.validate[Seq[FieldItem]] match { case JsSuccess(items, _) if items.nonEmpty => items.head.value case _ => "" }, str => str ) rowFiltered.set("field", fieldValue)
内容的提问来源于stack exchange,提问作者Mateusz Osinski
相关产品推荐
相关产品推荐

