例如我的json数据就像:
[{ "name": "Foo", "verified": {"email": true, "mobile": false} }, { "name": "Bar", "verified": {"email": false, "mobile": false} }]
使用json4s我可以获取一个JArray,在提取到User(case类)列表之前我想操作JArray - 我想要展平verified
字段,这样用户会是这样的:
case class (name: String, emailVerified: Boolean, mobileVerified: Boolean)
我该怎么做?
答案 0 :(得分:2)
您可以像这样转换现有的AST:
import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.json4s.JsonDSL._
object test extends App {
val json = """[{
| "name": "Foo",
| "verified": {"email": true, "mobile": false}
|}, {
| "name": "Bar",
| "verified": {"email": false, "mobile": false}
|}]""".stripMargin
def t(js: JValue): JValue = for {
JString(name) <- js \ "name"
JBool(ver1) <- js \ "verified" \ "email"
JBool(ver2) <- js \ "verified" \ "mobile"
} yield ("name" -> name) ~ ("emailVerified" -> ver1) ~ ("mobileVerified" -> ver2)
for {
JArray(xs) <- parse(json)
} yield JArray(xs map t)
}
另一种选择是为它编写自定义序列化程序:
import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.json4s.JsonDSL._
object userTest extends App {
val json = """{
| "name": "Bar",
| "verified": {"email": false, "mobile": false}
|}""".stripMargin
case class UserFoo(name: String, emailVerified: Boolean, mobileVerified: Boolean)
class UserFooSerializer extends CustomSerializer[UserFoo](formats => ( {
case js: JValue =>
val u = for {
JString(name) <- js \ "name"
JBool(userVerified) <- js \ "verified" \ "email"
JBool(mobileVerified) <- js \ "verified" \ "mobile"
} yield UserFoo(name, userVerified, mobileVerified)
u.head
}, Map.empty))
implicit val formats = DefaultFormats + new UserFooSerializer
parse(json).extractOpt[UserFoo] map {
user =>
println(user)
// UserFoo(Bar,false,false)
println(pretty(Extraction.decompose(user)))
// {
// "name" : "Bar",
// "emailVerified" : false,
// "mobileVerified" : false
// }
}
}