lift-json リファレンス
参考: JSON Support | Lift Project | Assembla
Scala標準にもjsonパーサとかありますが、lift-jsonのほうが人気。
基礎知識
A central concept in lift-json library is JSON AST (Abstract Syntax Tree) which models the structure of a JSON document as a syntax tree; all features are implemented in terms of AST. It provides a case class for each of the above mentioned JSON primitive and structured type, and provides functions used to transform the AST itself, or to transform the AST between different formats.
図でまとめるとこうなると。
以下ひたすら使い方 & サンプル
import
package objectをimportすることでJValueとかparse,renderなどのメソッドが使えるようになります。
import net.liftweb.json._
Json文字列 -> JsonAST
parse を使う
val data = """ { "name": "joe", "address": { "street": "Bulevard", "city": "Helsinki" }, "children": [ { "name": "Mary", "age": 5 "birthdate": "2004-09-04T18:06:22Z" }, { "name": "Mazy", "age": 3 } ] } """ val json = parse(data) println(json) /* JObject(List(JField(name,JString(joe)), JField(address,JObject(List(JField(street,JString(Bulevard)), JField(city,JString(Helsinki))))), JField(children, JArray( List(JObject(List(JField(name,JString(Mary)), JField(age,JInt(5)), JField(birthdate,JString(2004-09-04T18:06:22Z)))), JObject(List(JField(name,JString(Mazy)), JField(age,JInt(3))))))))) */
JsonASTからの値の取り出し
for で子供の名前を取り出してみます。
for { JObject(items) <- json item <- items JField("children", JArray(children)) <- item JObject(child) <- children JField("name", JString(name))<- child } { println(name) } /* Mary Mazy */
for式便利。でもちょっとがんばってる感ありますね。
XPathのような書き方で取り出すこともできます。
println(json \\ "children" \ "name") /* JArray(List(JField(name,JString(Mary)), JField(name,JString(Mazy)))) */
JsonAST -> case class
extract を使うと case class へのマッピングができます。
case class Person(name: String, address: Address, children: List[Child]) case class Address(street: String, city: String) case class Child(name: String, age: Int, birthdate: Option[java.util.Date]) println(json.extract[Person]) /* Person(joe,Address(Bulevard,Helsinki),List(Child(Mary,5,Some(Sun Sep 05 03:06:22 JST 2004)), Child(Mazy,3,None))) */
2012/01/05 追記
↓こういうこともできるらしい
Lift Json の case class への変換がとても便利な件 - scalaとか・・・
JsonAST -> Json文字列
render で scala.text.Document にしてから pretty or compact
println(compact(render(json))) /* {"name":"joe","address":{"street":"Bulevard","city":"Helsinki"},"children":[{"name":"Mary","age":5,"birthdate":"2004-09-04T18:06:22Z"},{"name":"Mazy","age":3}]} */ println(pretty(render(json))) /* { "name":"joe", "address":{ "street":"Bulevard", "city":"Helsinki" }, "children":[{ "name":"Mary", "age":5, "birthdate":"2004-09-04T18:06:22Z" },{ "name":"Mazy", "age":3 }] } */
case class -> Json文字列
Serialization.write を使います。
import org.scala_tools.time.Imports._ implicit val format = DefaultFormats println(Serialization.write( List(Person("joe" ,Address("Bulevard", "Helsinki"), List(Child("Mary", 5 ,Some(DateTime.now - 5.year toDate)), Child("Mazy", 3, None))), Person("john" ,Address("Bulevard", "Helsinki"), List(Child("Mary", 5 ,Some(DateTime.now - 5.year toDate)), Child("Mazy", 3, None)))) )) /* [{"name":"joe","address":{"street":"Bulevard","city":"Helsinki"},"children":[{"name":"Mary","age":5,"birthdate":"2007-01-03T06:55:16Z"},{"name":"Mazy","age":3}]}, {"name":"john","address":{"street":"Bulevard","city":"Helsinki"},"children":[{"name":"Mary","age":5,"birthdate":"2007-01-03T06:55:16Z"},{"name":"Mazy","age":3}]}] */ }
JsonDSLを使ってJsonASTを組み立てる
DSLと言うほどのものではない気がする。
Map -> JValue, Option[A] -> JValue, Int -> JInt などの implicit conversionがいろいろ定義されているのと
あと(String, A)がJsonAssoc[A]ってのに変換されて、そのおかげで "~" というメソッドが使えるようになります。
import net.liftweb.json.JsonDSL._ val beatles: JValue = ("Guitar" -> List("John", "George")) ~ ("Bass" -> "Paul") ~ ("Ringo" -> "Drums") println(pretty(render(beatles))) /* { "Guitar":["John","George"], "Bass":"Paul", "Ringo":"Drums" } */