因为最近在编写scala程序,就发现了使用play框架来方便的解析json数据。
一. 官网的解释是这样的:
1. 解析类库位于 play.api.libs.json._ 包。
2. 可以解析json字符串,可以创建json字符串。基于java的JSON库和jackson。
3. 可以在java和scala之间共享jackson底层库。
4. 可以享受play框架提供的额外的类型安全和函数编程的体验。
5. JSON is an AST (Abstract Syntax Tree).
二.支持的数据类型:
play.api.libs.json
package contains 7 JSON data types reflecting exactly the previous structure.
{ "name" : "toto", "age" : 45 }
as a JSON example. This represents null
value in JSON
This is a boolean with value true
or false
short
, int
, long
, float
, double
, bigdecimal
so it is represented by JsNumber
containing a bigdecimal
.[ "alpha", "beta", true, 123.44, 334]
as a JSON example.A classic String.
This is not part of the JSON standard and is only used internally by the API to represent some error nodes in the AST.
All previous types inherit from the generic JSON trait, JsValue
com.typesafe.play
play-json_2.10
2.4.0-M1
com.fasterxml.jackson.core
jackson-core
2.1.0
com.fasterxml.jackson.core
jackson-databind
2.1.0
com.fasterxml.jackson.core
jackson-annotations
2.1.0
1.解析并访问json树:
// play 框架json解析
val str = "{\"userid\" : \"011BBF43B89BFBF266C865DF0397AA71\", \"event_time\" : 1467093276663, \"event_type\" : \"Android\", \"click_count\" : 1}"
val parseObj = Json.parse(str)
val userid = (parseObj \ "userid").as[String]
val event_time = (parseObj \ "event_time").as[Long]
val event_type = (parseObj \ "event_type").as[String]
val click_count = (parseObj \ "click_count").as[Int]
println(userid)
println(event_time)
println(event_type)
println(click_count)
println("-" * 60)
val str2 =
"""
|{"person" : [
| {"name" : "zhangsan", "age" : 24, "iphone" : "12345678" },
| {"name" : "lisi", "age" : 20, "iphone" : "123454321" }
|]}
""".stripMargin
val persons = Json.parse(str2)
val names = persons \ "person" \\ "name"
println(names)
println("-"*60)
val json: JsValue = Json.parse("""{
"user": {
"name" : "toto","age" : 25,"email" : "[email protected]","isAlive" : true,
"friend" : {
"name" : "tata","age" : 20,"email" : "[email protected]"
}
}
}
""")
val emails = json \ "user" \\ "email"
println(emails)
011BBF43B89BFBF266C865DF0397AA71
1467093276663
Android
1
------------------------------------------------------------
ListBuffer("zhangsan", "lisi")
------------------------------------------------------------
List("[email protected]", "[email protected]")
五. 将JsValue类型转换成Scala的数据类型:
play-json解析出来的都是JsValue类型,我们可以将其强制转换成scala的简单数据类型。
Json.as[T] 这种方式上面的例子已经给出,但这种方式是不安全的,可能出现转换异常。
scala> val maybeName: Option[String] = (json \ "user" \ "name").asOpt[String]
maybeName: Option[String] = Some(toto)
case KO: 找不到Path
scala> val nameXXX: String = (json \ "user" \ "nameXXX").as[String]
play.api.libs.json.JsResultException: JsResultException(errors:List((,List(ValidationError(validate.error.expected.jsstring,WrappedArray())))))
at play.api.libs.json.JsValue$$anonfun$4.apply(JsValue.scala:65)
at play.api.libs.json.JsValue$$anonfun$4.apply(JsValue.scala:65)
at play.api.libs.json.JsResult$class.fold(JsResult.scala:69)
at play.api.libs.json.JsError.fold(JsResult.scala:10)
at play.api.libs.json.JsValue$class.as(JsValue.scala:63)
at play.api.libs.json.JsUndefined.as(JsValue.scala:96)
case KO: 非实际类型的转换
scala> val name: Long = (json \ "user" \ "name").as[Long]
play.api.libs.json.JsResultException: JsResultException(errors:List((,List(ValidationError(validate.error.expected.jsnumber,WrappedArray())))))
at play.api.libs.json.JsValue$$anonfun$4.apply(JsValue.scala:65)
at play.api.libs.json.JsValue$$anonfun$4.apply(JsValue.scala:65)
at play.api.libs.json.JsResult$class.fold(JsResult.scala:69)
at play.api.libs.json.JsError.fold(JsResult.scala:10)
at play.api.libs.json.JsValue$class.as(JsValue.scala:63)
at play.api.libs.json.JsString.as(JsValue.scala:111)
case OK: 正常情况的转换
scala> val maybeName: Option[String] = (json \ "user" \ "name").asOpt[String]
maybeName: Option[String] = Some(toto)
case KO: 未找到的路径
scala> val maybeNameXXX: Option[String] = (json \ "user" \ "nameXXX").asOpt[String]
maybeNameXXX: Option[String] = None
case KO: 非实际类型转换
scala> val maybeNameLong: Option[Long] = (json \ "user" \ "name").asOpt[Long]
maybeNameLong: Option[Long] = None