scala解析json —— json4s 解析json方法彙總

使用json4s的框架,包括spark,flinkjava

一、org.json4s 引入pom的方法

對於本地支持,引入如下依賴項添加到pom中json

<dependency>
  <groupId>org.json4s</groupId>
  <artifactId>json4s-jackson_${scala.version}</artifactId>
  <version>{latestVersion}</version>
</dependency>

對於jackson支持,引入如下依賴項添加到pom中數組

<dependency>
  <groupId>org.json4s</groupId>
  <artifactId>json4s-jackson_${scala.version}</artifactId>
  <version>{latestVersion}</version>
</dependency>

二、Json4s 數據類型

json4s類型包括兩個10個類型和一個type類型對象安全

case object JNothing extends JValue // 'zero' for JValue
case object JNull extends JValue
case class JString(s: String) extends JValue
case class JDouble(num: Double) extends JValue
case class JDecimal(num: BigDecimal) extends JValue
case class JInt(num: BigInt) extends JValue
case class JLong(num: Long) extends JValue
case class JBool(value: Boolean) extends JValue
case class JObject(obj: List[JField]) extends JValue
case class JArray(arr: List[JValue]) extends JValue
 
type JField = (String, JValue)

JField再也不是JValue這意味着更高的類型安全性,由於再也不可能建立無效的JSON,例如 JFields 直接添加到JArrays中,此更改最明顯的結果是map、transform、find和filter有兩種版本:框架

def map(f: JValue => JValue): JValue
def mapField(f: JField => JField): JValue
def transform(f: PartialFunction[JValue, JValue]): JValue
def transformField(f: PartialFunction[JField, JField]): JValue
def find(p: JValue => Boolean): Option[JValue]
def findField(p: JField => Boolean): Option[JField]

三、使用org.json4s解析json字符串

 提取不嵌套的json串spa

import org.json4s._
import org.json4s.native.JsonMethods._

// parse解析返回值爲Jvalue
scala> parse("""{"name":"Toy","price":35.35}""", useBigDecimalForDouble = true)
res1: org.json4s.package.JValue = 
      JObject(List((name,JString(Toy)), (price,JDecimal(35.35))))

 提取json中的元素的值
1)單層嵌套取單值.net

//val parseJson: JValue = parse( """{"name":"Toy","price":35.35}""", useBigDecimalForDouble = true)
val parseJson: JValue = parse( """{"name":"Toy","price":35.35}""")

// 方法一:JString模式匹配方式
val JString(name) = (parseJson \ "name")
println(name)

//方法二:extract[String]提取值,
val name:String = (parseJson \ "name").extract[String] // 直接提取內容(不安全)
val name:Option[String] = (parseJson \ "name").extractOpt[String]// 返回Option類型(安全)
val name: String = (parseJson \ "name").extractOrElse[String]("") // 設置默認值

2)多層嵌套套取單值scala

val parseJson: JValue = parse( """{"name":{"tome":"new"},"price":35.35}""", useBigDecimalForDouble = true)
println(parseJson)
// 方法一:逐層訪問
val value: String = (parseJson \ "name" \ "tome").extract[String]
// 方法二:循環訪問
val value: String = (parseJson \\ "tome").extract[String]

解析提取數組的json串code

簡單值數組orm

// 解析列表
parse(""" { "numbers" : [1, 2, 3, 4] } """)
res0: org.json4s.JsonAST.JValue =
      JObject(List((numbers,JArray(List(JInt(1), JInt(2), JInt(3), JInt(4))))))

// 程序解析
val listValue : List[BigInt]  = for {JArray(child) <- jArray; JInt(value) <- child} yield value

listValue.map(println)

嵌套數組json串解析

val json = parse(
      """
         { "name": "joe",
           "children": [
             {
               "name": "Mary",
               "age": 5
             },
             {
               "name": "Mazy",
               "age": 3
             }
           ]
         }
      """)

// 嵌套返回值
for (JArray(child) <- json) println(child)
res0: List(JObject(List((name,JString(Mary)), (age,JInt(5)))), JObject(List((name,JString(Mazy)), (age,JInt(3)))))

// 嵌套取數組中某個字段值
for {
   JObject(child) <- json
   JField("age", JInt(age)) <- child
} yield age

// 嵌套取數組中某個字段值,並添加過濾
for {
  JObject(child) <- json
  JField("name", JString(name)) <- child
  JField("age", JInt(age)) <- child
  if age > 4
} yield (name, age)

json和對象的轉換

/** json轉化爲對象(不帶外層字段) **/
case class ClassA(a: Int, b: Int)

val json2: String = """[{"a":1,"b":2},{"a":1,"b":2}]"""

val bb: List[ClassA] = parse(json2).extract[List[ClassA]]

println(bb)

/** json轉對象(帶外層字段名) */
case class ClassC(a: Int, b: Int)

case class ClassB(c: List[ClassC])

val json3: String = """{"c":[{"a":1,"b":2},{"a":1,"b":2}]}"""

val cc: ClassB = parse(json3).extract[ClassB]

println(cc)

四、使用org.json4s產生json字符串

基本數據類型轉化爲普通json
1) 序列Seq轉化爲Json字符串

scala> val json = List(1, 2, 3)

scala> compact(render(json))
res0: String = [1,2,3]

2) Tuple2[String, A] 類型轉化爲json字符串

scala> val json = ("name" -> "joe")

scala> compact(render(json))
res1: String = {"name":"joe"}

3) ~ 合併object對象轉化爲json串

scala> val json = ("name" -> "joe") ~ ("age" -> 35)

scala> compact(render(json))
res2: String = {"name":"joe","age":35}

4) option 類型轉化爲串

scala> val json = ("name" -> "joe") ~ ("age" -> Some(35))

scala> compact(render(json))
res3: String = {"name":"joe","age":35}

scala> val json = ("name" -> "joe") ~ ("age" -> (None: Option[Int]))

scala> compact(render(json))
res4: String = {"name":"joe"}

5) case class 類轉化爲Json串

object JsonExample extends App {
  import org.json4s._
  import org.json4s.JsonDSL._
  import org.json4s.jackson.JsonMethods._

  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" ->
      ("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)))
}

五、使用org.json4s其餘用法

1) 格式化json串

scala> pretty(render(JsonExample.json))

{
  "lotto":{
    "lotto-id":5,
    "winning-numbers":[2,45,34,23,7,5,3],
    "winners":[{
      "winner-id":23,
      "numbers":[2,45,34,23,3,5]
    },{
      "winner-id":54,
      "numbers":[52,3,12,11,18,22]
    }]
  }
}

2) 合併兩個json 串

scala> import org.json4s._
scala> import org.json4s.jackson.JsonMethods._

scala> val lotto1 = parse("""{
         "lotto":{
           "lotto-id":5,
           "winning-numbers":[2,45,34,23,7,5,3],
           "winners":[{
             "winner-id":23,
             "numbers":[2,45,34,23,3,5]
           }]
         }
       }""")

scala> val lotto2 = parse("""{
         "lotto":{
           "winners":[{
             "winner-id":54,
             "numbers":[52,3,12,11,18,22]
           }]
         }
       }""")

scala> val mergedLotto = lotto1 merge lotto2

scala> pretty(render(mergedLotto))
res0: String =
{
  "lotto":{
    "lotto-id":5,
    "winning-numbers":[2,45,34,23,7,5,3],
    "winners":[{
      "winner-id":23,
      "numbers":[2,45,34,23,3,5]
    },{
      "winner-id":54,
      "numbers":[52,3,12,11,18,22]
    }]
  }
}

3) 兩個json 串查找差別

scala> val Diff(changed, added, deleted) = mergedLotto diff lotto1
changed: org.json4s.JsonAST.JValue = JNothing
added: org.json4s.JsonAST.JValue = JNothing
deleted: org.json4s.JsonAST.JValue = JObject(List((lotto,JObject(List(JField(winners,
JArray(List(JObject(List((winner-id,JInt(54)), (numbers,JArray(
List(JInt(52), JInt(3), JInt(12), JInt(11), JInt(18), JInt(22))))))))))))))

 

> 參考連接:https://blog.csdn.net/leehbing/article/details/74391308

相關文章
相關標籤/搜索