使用play框架来解析json字符串

参考:https://playframework.com/documentation/2.1.x/ScalaJson#json-data-types

https://blog.csdn.net/liuhui_306/article/details/51777471

因为最近在编写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.

JsObject

  • This is a set of name/value pairs as described in standard.
  • { "name" : "toto", "age" : 45 } as a JSON example.

JsNull

This represents null value in JSON

JsBoolean

This is a boolean with value true or false

JsNumber

  • JSON does NOT discriminate short, int, long, float, double, bigdecimalso it is represented by JsNumber containing a bigdecimal.
  • Play JSON API brings more type precision when converting to Scala structures.

JsArray

  • An array is a sequence of any Json value types (not necessarily the same type).
  • [ "alpha", "beta", true, 123.44, 334] as a JSON example.

JsString

A classic String.

JsUndefined

This is not part of the JSON standard and is only used internally by the API to represent some error nodes in the AST.

JsValue

All previous types inherit from the generic JSON trait, JsValue

三. maven依赖:

<dependency>

    <groupId>com.typesafe.play</groupId>

    <artifactId>play-json_2.10</artifactId>

    <version>2.4.0-M1</version>

</dependency>

<dependency>

    <groupId>com.fasterxml.jackson.core</groupId>

    <artifactId>jackson-core</artifactId>

    <version>2.1.0</version>

</dependency>

<dependency>

    <groupId>com.fasterxml.jackson.core</groupId>

    <artifactId>jackson-databind</artifactId>

    <version>2.1.0</version>

</dependency>

<dependency>

    <groupId>com.fasterxml.jackson.core</groupId>

    <artifactId>jackson-annotations</artifactId>

    <version>2.1.0</version>

</dependency>

四. 代码例子:

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]")

由例子可以看出,每出现一个 \ 表示从父节点开始只访问一层,每出现一个 \\ 表示从父节点开始递归式的查找父节点下每一个符合key的值。

五. 将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)

但可以使用比较安全的一种方式 Json.asOpt[Option[T]]:

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

猜你喜欢

转载自blog.csdn.net/hellojoy/article/details/81558496
今日推荐