0

例如我的 json 数据是这样的:

[{
  “名称”:“Foo”,
  “已验证”:{“电子邮件”:真,“手机”:假}
}, {
  “名称”:“酒吧”,
  “已验证”:{“电子邮件”:假,“手机”:假}
}]

使用 json4s 我可以获得一个 JArray,在提取到用户列表(案例类)之前,我想操作 JArray - 我想展平该verified字段,以便用户如下所示:

case class (name: String, emailVerified: Boolean, mobileVerified: Boolean)

我怎样才能做到这一点?

4

1 回答 1

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
      // }
  }

}
于 2014-01-29T23:49:17.563 回答