使用 json4s 解析 JSON 中的空值
Parsing null values in JSON using json4s
我在我的项目中使用 json4s 库来逐个字段手动解析 JSON(不会自动反序列化为大小写 类)。
例如我有以下JSON:
{
result: "OK",
persons: [
{name: "Alex"},
{name: null}
]
}
官方指南建议使用这种方法手动解析它:
for {
JArray(persons) <- json / "persons"
JObject(person) <- persons
JField("name", JString(name)) <- person
} yield Person(name)
问题是这种理解会跳过具有 null
个名字的人。我认为这是因为在理解中我使用了 JString(name)
,所以它需要一些 String
值,而不是 null
.
有什么办法可以解决吗?我只想遍历数组并访问每个对象(即使它有 null
而不是一些 String
)
是的,你已经知道它不能工作的原因了,你只需要像下面这样改变模式匹配。
case class Person(name: String)
// the result is actually List[Option[Person]]
val result =
for {
JArray(persons) <- json \ "persons"
JObject(person) <- persons
// jv is JsonAST.JValue
JField("name", jv) <- person
} yield {
// in case of match error so add _ here
jv match {
case JString(name) => Some(Person(name))
case JNull => Some(Person(null))
case _ => None
}
}
实际上,在您提到的文档中的 Extracting values 部分之后还有另一种更简单的方法。
case class Person(name: String)
import org.json4s.DefaultFormats
implicit val formats = DefaultFormats // Brings in default date formats etc
val result2 = (json \ "persons").extract[List[Person]]
// List(Person(Alex), Person(null))
println(result2)
这样就可以了,
val r:List[Person] = for {
JArray(persons) <- JsonMethods.parse(json) \ "persons"
JObject(person) <- persons
//JField("name", JString(name)) <- person
p = Person(person.head._2) //or Person(person.find(_._1=="name").map(_._2).getOrElse(null))
} yield p
println(r) //List(Person("Alex"), Person(null))
我在我的项目中使用 json4s 库来逐个字段手动解析 JSON(不会自动反序列化为大小写 类)。
例如我有以下JSON:
{
result: "OK",
persons: [
{name: "Alex"},
{name: null}
]
}
官方指南建议使用这种方法手动解析它:
for {
JArray(persons) <- json / "persons"
JObject(person) <- persons
JField("name", JString(name)) <- person
} yield Person(name)
问题是这种理解会跳过具有 null
个名字的人。我认为这是因为在理解中我使用了 JString(name)
,所以它需要一些 String
值,而不是 null
.
有什么办法可以解决吗?我只想遍历数组并访问每个对象(即使它有 null
而不是一些 String
)
是的,你已经知道它不能工作的原因了,你只需要像下面这样改变模式匹配。
case class Person(name: String)
// the result is actually List[Option[Person]]
val result =
for {
JArray(persons) <- json \ "persons"
JObject(person) <- persons
// jv is JsonAST.JValue
JField("name", jv) <- person
} yield {
// in case of match error so add _ here
jv match {
case JString(name) => Some(Person(name))
case JNull => Some(Person(null))
case _ => None
}
}
实际上,在您提到的文档中的 Extracting values 部分之后还有另一种更简单的方法。
case class Person(name: String)
import org.json4s.DefaultFormats
implicit val formats = DefaultFormats // Brings in default date formats etc
val result2 = (json \ "persons").extract[List[Person]]
// List(Person(Alex), Person(null))
println(result2)
这样就可以了,
val r:List[Person] = for {
JArray(persons) <- JsonMethods.parse(json) \ "persons"
JObject(person) <- persons
//JField("name", JString(name)) <- person
p = Person(person.head._2) //or Person(person.find(_._1=="name").map(_._2).getOrElse(null))
} yield p
println(r) //List(Person("Alex"), Person(null))