如何在Scala中解析复杂的json

时间:2015-09-18 04:18:11

标签: json scala playframework

我是Scala中的真正新手(使用Play框架)并试图找出解析复杂JSON的最佳方法。

这是我的一个例子:     {        " ID":" TEST1&#34 ;,        " t最大":270,        "在":2,        " BCAT":[           " IAB26&#34 ;,           " IAB25&#34 ;,           " IAB24"        ],

   "imp":[
      {
         "id":"1",
         "banner":{
            "w":320,
            "h":480,
            "battr":[
               10
            ],
            "api":[
            ]
         },
         "bidfloor":0.69
      }
   ],
   "app":{
      "id":"1234",
      "name":"Video Games",
      "bundle":"www.testapp.com",
      "cat":[
         "IAB1"
      ],
      "publisher":{
         "id":"1111"
      }
   },
   "device":{
      "dnt":0,
      "connectiontype":2,
      "carrier":"Ellijay Telephone Company",
      "dpidsha1":"e5f61ae0597d8abee94860d66f7d512aa68d0985",
      "dpidmd5":"c1827fe90bae819017dfdb30db7e84fa",
      "didmd5":"1f6cb9dc519db8e48cf9592b31cce04e",
      "didsha1":"2e6a5d7f5fd1b2b5dea56a80f2b9dc24902a0ca7",
      "ifa":"422aeb3a-6507-40b5-9e6f-42a0e14b51be",
      "osv":"4.4",
      "os":"Android",
      "ua":"Mozilla/5.0 (Linux; Android 4.4.2; DL1010Q Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36",
      "ip":"24.75.160.74",
      "devicetype":1,
      "geo":{
         "type":1,
         "country":"USA",
         "city":"Jasper"
      }
   },
   "user":{
      "id":"9c2be7c2a3dfe19070f193910e92b2e0"
   },
   "cur":[
      "USD"
   ]
   }

非常感谢!

3 个答案:

答案 0 :(得分:4)

我会使用http://json4s.org/#extracting-values中描述的案例类,例如

scala> import org.json4s._
scala> import org.json4s.jackson.JsonMethods._
scala> implicit val formats = DefaultFormats // Brings in default date formats etc.
scala> case class Child(name: String, age: Int, birthdate: Option[java.util.Date])
scala> case class Address(street: String, city: String)
scala> case class Person(name: String, address: Address, children: List[Child])
scala> val json = parse("""
        { "name": "joe",
          "address": {
            "street": "Bulevard",
            "city": "Helsinki"
          },
          "children": [
            {
              "name": "Mary",
              "age": 5,
              "birthdate": "2004-09-04T18:06:22Z"
            },
            {
              "name": "Mazy",
              "age": 3
            }
          ]
        }
      """)

scala> json.extract[Person]
res0: Person = Person(joe,Address(Bulevard,Helsinki),List(Child(Mary,5,Some(Sat Sep 04 18:06:22 EEST 2004)), Child(Mazy,3,None)))

答案 1 :(得分:2)

使用implicit来自动获取具有相同名称的json值。

如果您有像

这样的字符串
    val jsonString =
   { "company": {
            "name": "google",
            "department": [
               {
                   "name": "IT",
                   "members": [
                     {
                        "firstName": "Max",
                        "lastName": "Joe",
                        "age" : 25
                     },
                     {
                        "firstName": "Jean",
                        "lastName": "Nick",
                        "age" : 55,
                        "salary": 100,000
                     }
                   ]
               },
               {
                   "name": "Marketing"
                   "members": [
                      {
                        "firstName": "Mike",
                        "lastName": "Lucas",
                        "age" : 43 
                      }
                   ] 
               },
            ]
        }
       }

然后我们应该按照以下步骤将其解析为scala对象

val json: JsValue = Json.parse(jsonString)    // string to JsValue
case class Person(firstName: String, lastName: String, age: Int, salary: Option[Int]) // keep the lower level object above since you will use them below
implicit personR = Json.reads[Person]  
// implicit will read the json attribute if you use the same name as it is in json String. For example "name" : "google" will be read if you have Company(name: String). See the "name" and name:String .

case class Department(name: String, members: Seq[Person])
implicit departmentR = Json.reads[Department]

case class Company(name: String, department: Seq[Department])
implicit val companyR = Json.reads[Company]

val result = json.validate[Company] match {
  case s: JsSuccess[Company] => s.get  // s.get will return a Company object 
  case e: JsError => println("error")
}

答案 2 :(得分:0)

不知道它是否可以单独使用,但Play Framework有很好的工具可以使用JSON。看看here