Scala Json4s
ooyalaの記事だと,json4sを推奨していた.
パフォーマンス比較もしている.
json4s
jacksonとnative(pure scala)がある.
json4s-jacksonを使う.
Producing Json
基本的に
(key -> value) ~ (key -> value)
のように,kvのペアを結合していく
ProcudeJsonSample.scala
package edu.kzk.io.json4s import org.json4s._ import org.json4s.JsonDSL._ import org.json4s.jackson.JsonMethods._ object ProcudeJsonSample extends App { case class Winner(id: Long, numbers: List[Int]) case class Lotto(id: Long, winningNumbers: List[Int], winners: List[Winner], drawDate: Option[java.util.Date]) val winners = List(Winner(23, List(2, 45, 34, 23, 3, 5)), Winner(54, List(52, 3, 12, 11, 18, 22))) val lotto = Lotto(5, List(2, 45, 34, 23, 7, 5, 3), winners, None) val json = ("lotto-id" -> lotto.id) ~ ("winning-numbers" -> lotto.winningNumbers) ~ ("draw-date" -> lotto.drawDate.map(_.toString)) ~ ("winners" -> lotto.winners.map { w => (("winner-id" -> w.id) ~ ("numbers" -> w.numbers)) }) println(compact(render(json))) }
Quering json (LINQ-style)
LINQ-styleでjson objectに対してクエリを投げる.
LINQSample.scala
package edu.kzk.io.json4s import org.json4s._ import org.json4s.jackson.JsonMethods._ object LINQSample extends App { // json value val jvalue = parse(""" { "name": "joe", "age": 33, "children": [ { "name": "Mary", "age": 5 }, { "name": "Mazy", "age": 3 } ] } """) println(pretty(render(jvalue))) val value = jvalue.values; println(value) // LINQ-style val queryResults = for { JObject(child) <- jvalue JField("age", JInt(age)) <- child } yield age println(queryResults) }
Querying json (XPath)
GitHubのサンプルだと,\, \\が定義されてないので使えないとEclipseに怒られる.
型が(String, JObject)になっており,その原因は(xxx -> yyy)で,jsonのトップレベルがmapで認識されているから.
なので,renderしてJValueにしている.
- XpathSample.scala
package edu.kzk.io.json4s object XpathSample extends App { import org.json4s._ import org.json4s.JsonDSL._ import org.json4s.jackson.JsonMethods._ import com.fasterxml.jackson.annotation.JsonValue // json value val jvalue = render( ("person" -> ("name" -> "Joe") ~ ("age" -> 35) ~ ("spouse" -> ("person" -> ("name" -> "Marilyn") ~ ("age" -> 33) ) ) )) // \\ sample var extractedJsonValue = jvalue \\ "spouse"; println(compact(extractedJsonValue)) // \\ concatenation sample extractedJsonValue = jvalue \\ "spouse" \\ "person" \\ "age" println(compact(extractedJsonValue)) // findField sample val jField = jvalue findField { case JField("name", _) => true case _ => false } println(jField.get._2.values) // unboxed value // filterField sample val jFilterFields = jvalue filterField { case JField("name", _) => true case _ => false } println(jFilterFields) }
Extracting value
Jsonからデータを抜き出して,対応するあるクラスのオブジェクトをつくる.
- case classを作る
case class Child(name: String, age: Int, birthdate: Option[java.util.Date]) case class Address(street: String, city: String) case class Person(name: String, address: Address, children: List[Child])
- parseでJValueを作る
val jvalue = parse(""" ... """
- extract
val person = jvalue.extract[Person]
nullの可能性のあるフィールドはOptionをつけること
ExtractAsCaseClassSample.scala
package edu.kzk.io.json4s import org.json4s._ import org.json4s.jackson.JsonMethods._ object ExtractAsCaseClassSample extends App { implicit val formats = DefaultFormats // Brings in default date formats etc. case class Child(name: String, age: Int, birthdate: Option[java.util.Date]) case class Address(street: String, city: String) case class Person(name: String, address: Address, children: List[Child]) // json value val jvalue = parse(""" { "name": "joe", "address": { "street": "Bulevard", "city": "Helsinki" }, "children": [ { "name": "Mary", "age": 5, "birthdate": "2004-09-04T18:06:22Z" }, { "name": "Mazy", "age": 3 } ] } """) val person = jvalue.extract[Person] println(person) // val address = json.extract[Address] // println(address) }
参考
http://engineering.ooyala.com/blog/comparing-scala-json-libraries
http://qiita.com/suin/items/f69e1e9ca638538e6e27
http://kakakakakku.hatenablog.com/entry/2014/04/23/204254
http://stackoverflow.com/questions/23531065/scala-parse-json-directly-into-a-case-class
http://json4s.org/
https://github.com/json4s/json4s
http://mvnrepository.com/artifact/org.json4s
http://mvnrepository.com/artifact/io.spray